﻿//Gestiona Tiles de la capa vectorial
function WVVectorLayer()
{
    var oThis = this;
    var panel = null;
    var viewer = null;
    var layerType = WVLayerType.VECTOR;
    var visible = true;
    
    var rows = 0;
    var cols = 0;
    var widthGrid   = 0;
    var heightGrid  = 0;
    var widthTileUtmX  = 0;
    var heightTileUtmY = 0;
    
    var queryRefresh;
    this.tilesRemaining = 0; 
    var seedCache=0; //semilla para forzar la actualización de la capa con datos nuevos
    
    var numLayersBehind = 0; // número de capas que existen debajo de ésta
    var refCenterUtm; //UTM central de referencia para construir Supertile
    var imgTranspURL = "";
    
    this.init = function(webviewer)
    {
        viewer = webviewer;
        imgTranspURL = document.getElementById(viewer.getBaseID() + viewer.getGUID() + "_imgTranspSrc").value;
        
        numLayersBehind = viewer.getSystemLayers().length - 1;
        setupReferences();
        setupPanel();
        calcRowsAndCols();
        setupGrid();
        viewer.subscribeEvent(WVEventType.CHANGE_SCALE, this.onChangeScale);
        queryRefresh=false;
    }
    
    //Retorna si se ha completado la carga de esta capa
    this.isLoaded=function()
    {
        return this.tilesRemaining > 0 ? false : true;
    }
    
    this.setVisible=function(ver)
    {
        visible = ver;
        if (!visible)
        {
            panel.style.visibility= "hidden";
        }
        else
        {
            if (window.opera || window.addEventListener) this.renoveCache();
            queryRefresh=true;
        }
    }
    
    this.getVisible=function()
    {
        return visible;
    }
    
    this.getLayerType=function()
    {
        return layerType;
    }
    
    this.getContainer=function()
    {
        return panel;
    }
    
    this.getTiles = function ()
    {
        return panel.childNodes;
    }
    
    //Refresca la vista
    this.refresh = function ()
    {
        queryRefresh=true;
    }
    
    //Libera recursos
    this.dispose = function ()
    {
        disposeAll();
    }
    
    //Refresca la vista
    this.refresh=function()
    {
        queryRefresh=true;
    }
    
    //Scrolling de Tiles en base a un vector de desplazamiento
    this.onUpdate = function (offset)
    {
        if (visible)
        {
            if (queryRefresh)
            {
                refreshAll();
                queryRefresh=false;
                return;
            }
            
            if (viewer.getVectorOpacity())
            {
                for(var i=panel.childNodes.length-1;i>=0;i--) //Opacity
                {
                    setOpacity(panel.childNodes[i]);
                }
            }
            
            if (offset.x!=0 || offset.y!=0) //Scrolling
            {
                var vw = viewer.getWidth();
                var vh = viewer.getHeight();
                var tw = viewer.getTileWidth();
                var th = viewer.getTileHeight();
                
                var lstTiles=new Array();
                
                var i=rows-1;
                do
                {
                    var j=cols-1;
                    do
                    {
                        var tile = panel.childNodes[i * cols + j];
                        
                        if (tile!=null)
                        {
                            var tileX = parseInt(tile.style.left) + offset.x;
                            var tileY = parseInt(tile.style.top) + offset.y;
                            
                            var swappedX = 0;
                            var swappedY = 0;
                            if (offset.x > 0 && tileX >= vw) //Scroll por la derecha
                            {
                                tileX -= widthGrid;
                                swappedX = -1;
                            }
                            else if (offset.x < 0 && tileX < - tw) //Scroll por la izquierda
                            {
                                tileX += widthGrid;
                                swappedX = 1;
                            }
                            
                            if (offset.y < 0 && tileY < - th) //Scroll por arriba
                            {
                                tileY += heightGrid;
                                swappedY = -1;
                            }
                            else if (offset.y > 0 && tileY >= vh) //Scroll por abajo
                            {
                                tileY -= heightGrid;
                                swappedY = 1;
                            }
                                                        
                            if (swappedX!=0 || swappedY!=0)
                            {
                                hideTile(tile);
                                var superFactorX = parseInt(tile.getAttribute("supertileFactorX"));
                                var superFactorY = parseInt(tile.getAttribute("supertileFactorY"));
                                superFactorX+=swappedX;
                                superFactorY+=swappedY;
                                tile.setAttribute("supertileFactorX",superFactorX);
                                tile.setAttribute("supertileFactorY",superFactorY);
                                
                                lstTiles.push(tile);
                            }
                            
                            tile.style.left=tileX;
                            tile.style.top=tileY; 
                            
                            if (tile.getAttribute("NeedRefresh")=="true") //comprueba si algún tile dentro de la vista necesita recargarse
                            {
                                if ( (tileX<=viewer.getWidth() && tileX+256>=0) && (tileY<=viewer.getHeight() && tileY+256>=0) )
                                {
                                    lstTiles.push(tile);
                                }
                            }
                        }
                    }
                    while(j--)
                }
                while(i--)
                if (lstTiles.length>0) resolveTiles(sortTiles(viewer, lstTiles));
            }
        }
    }
    
    this.onChangeScale = function()
    {
        oThis.refresh();
    }
    
    this.onRedock=function()
    {
        panel.style.visibility = "hidden";
        oThis.refresh();
    }
    
    //Renueva la semilla caché para no obtener los mismos datos gráficos en el próximo refresco
    this.renoveCache=function()
    {
        seedCache++;
    }
    
    function refreshAll()
    {
        setupReferences();        

        var xIni = (viewer.getWidth()  >> 1) - (widthGrid  >> 1);
        var yIni = (viewer.getHeight() >> 1) - (heightGrid >> 1);
        var tw = viewer.getTileWidth();
        var th = viewer.getTileHeight();      
        
        var lstTiles=new Array();  
        
        var i=rows-1;
        do
        {
            var row = i * tw;
            var j=cols-1;
            do
            {
                var col = j * th;
                var tile = panel.childNodes[i * cols + j];
                if (tile!=null)
                {
                    hideTile(tile);
                    tile.onload=null;
                    tile.src=imgTranspURL;//"";
                    
                    tile.setAttribute("supertileFactorX", "0");
                    tile.setAttribute("supertileFactorY", "0");
                    
                    var x=xIni + col;
                    var y=yIni + row;
                    tile.style.top = y;
                    tile.style.left= x;   
                    tile.style.width=tw;
                    tile.style.height=th; 
                    
                    lstTiles.push(tile);
                }
            }
            while(j--);
        }
        while(i--);
        
        oThis.tilesRemaining = 0;
        resolveTiles(sortTiles(viewer, lstTiles));
        
        if (visible)
        {
            panel.style.visibility= "visible";
        }
    }
    
    function disposeAll()
    {
        viewer.unsubscribeEvent(WVEventType.CHANGE_SCALE, oThis.onChangeScale);
        var j=panel.childNodes.length-1;
        do
        {
            var tile = panel.childNodes[j];
            panel.removeChild(tile);
        }
        while(j--);
        panel.innerHTML="";
    }
    
    function setupReferences()
    {
        widthTileUtmX  = viewer.getTileWidth() *viewer.getScale();
        heightTileUtmY = viewer.getTileHeight()*viewer.getScale();
        refCenterUtm=viewer.getCenterUtm();
    }
    
    //Calcula filas y columnas de tiles que se necesitan para rellenar la capa
    function calcRowsAndCols()
    {
        rows = Math.ceil(viewer.getHeight()/viewer.getTileHeight()) + 1;
        cols = Math.ceil(viewer.getWidth()/viewer.getTileWidth()) + 1;
        
        widthGrid = viewer.getTileWidth() * cols;
        heightGrid = viewer.getTileHeight() * rows;
    }
    
    //Crea panel contenedor de Tiles
    function setupPanel(width, height)
    {
        //configura panel contenedor
        panel = document.createElement('DIV');
        panel.style.width=viewer.getWidth();
        panel.style.height=viewer.getHeight();
        panel.style.top=-viewer.getHeight()*numLayersBehind;
        panel.style.left=0;
        panel.style.position="relative";
        panel.style.display="block";
        panel.style.backgroundColor="transparent";
        panel.style.zIndex = viewer.getZIndexBase()+10;
    }
    
    //Crea Tiles necesarios para la visualización
    function setupGrid()
    {
        //construye Grid de Tiles empezando por la esquina superior izquierda
        var xIni = (viewer.getWidth()  >> 1) - (widthGrid  >> 1);
        var yIni = (viewer.getHeight() >> 1) - (heightGrid >> 1);
        var tw = viewer.getTileWidth();
        var th = viewer.getTileHeight();
        
        var indexDomain=0;
        var domains = viewer.getDomains();
        var domainStep=0;
        
        var lstTiles=new Array();
        
        var i=rows-1;
        do
        {
            var row = i * tw;
            
            var j=cols-1;
            do
            {
                if (domains.length>0)
                {
                    domainStep++;
                    if (domainStep>2)
                    {
                        domainStep=0;
                        indexDomain++;
                        indexDomain= indexDomain>=domains.length ? 0 : indexDomain;
                    }
                }
                
                var col = j * th;
                
                var tile = document.createElement('IMG');
                hideTile(tile);
                tile.setAttribute("indexDomain", indexDomain);
                tile.setAttribute("isMap", "true");
                tile.setAttribute("supertileFactorX", "0");
                tile.setAttribute("supertileFactorY", "0");
                tile.style.position  = "absolute";
                tile.style.width=tw;
                tile.style.height=th;
                
                //posición en coordenadas pantalla
                var x = xIni + col;
                var y = yIni + row;
                tile.style.top = y;
                tile.style.left= x;
                
                lstTiles.push(tile);
                panel.appendChild(tile);
            }
            while(j--);
        }
        while(i--);
        resolveTiles(sortTiles(viewer, lstTiles));
    }
    
    //evento que notifica la carga de un Tile
    function tileLoaded(e)
    {
        oThis.tilesRemaining--; //contador de tiles pendientes de carga
        oThis.tilesRemaining = oThis.tilesRemaining < 0 ? 0 : oThis.tilesRemaining;
        this.style.display="block";
        this.setAttribute("loading", "false");
    }
    
    //resuelve peticiones de tiles
    function resolveTiles(lstTiles)
    {
        var n = lstTiles.length;
        for(var i=0;i<n;i++)
        {
            var tile = lstTiles[i];
            resolveDirectPX(tile, parseInt(tile.style.left), parseInt(tile.style.top));

            hideTile(tile);
            tile.onload=null;
            tile.src=imgTranspURL;//null;
            if (tile.getAttribute("loading")=="true")
            {
                if (tile.getAttribute("NeedRefresh")=="false")
                {
                    tile.onload = tileLoaded;
                    tile.src = tile.getAttribute("NextURL");
                }
                else if (tile.getAttribute("NeedRefresh")=="true")
                {
                    tile.setAttribute("loading", "false");
                    oThis.tilesRemaining--; //contador de tiles pendientes de carga
                    oThis.tilesRemaining = oThis.tilesRemaining < 0 ? 0 : oThis.tilesRemaining;
                }
            }
        }
    }
    
    function resolveDirectPX(tile, px, py)
    {
        //si el tile está fuera de la vista, no lo carga
        if ( (px>viewer.getWidth() || px+256<0) || (py>viewer.getHeight() || py+256<0) )
        {
            tile.setAttribute("NeedRefresh","true");
            return;
        }
        
        var url = resolve(tile, px, py);
        tile.setAttribute("NeedRefresh","false");
        tile.setAttribute("NextURL", url);
        if (tile.getAttribute("loading")=="true") oThis.tilesRemaining--;
        tile.setAttribute("loading", "true");
        oThis.tilesRemaining++;
    }
    
    function resolve(tile, xLocal, yLocal)
    {
        var domain = getDomain(parseInt(tile.getAttribute("indexDomain")));
        
        var host = domain + viewer.getUrlBase()+"op=1&";
        var visor = "VisorID=" + viewer.getGUID() + "&";
        var v = viewer.transformLocalToWorld(xLocal, yLocal+ viewer.getTileHeight());
        var coords = "Args="+v.x+","+v.y+","+widthTileUtmX+","+heightTileUtmY+","+viewer.getTileWidth()+","+viewer.getTileHeight()+"&";
        var basura = "cacheSeed="+seedCache+"&scale="+viewer.getScale();
        
        //Supertile
        var scale=viewer.getScale();
        var sizeX = widthGrid * scale;
        var sizeY = heightGrid * scale;
        var superFactorX = tile.getAttribute("supertileFactorX");
        var superFactorY = tile.getAttribute("supertileFactorY");
        var centerX=refCenterUtm.x + (superFactorX * sizeX);
        var centerY=refCenterUtm.y + (superFactorY * sizeY);
        var utmXini=centerX - parseInt((widthGrid >> 1) * scale);
        var utmYini=centerY - parseInt((heightGrid >> 1) * scale);
        var vg = "&VG="+utmXini+","+utmYini+","+widthGrid+","+heightGrid;
        
        return host + visor + coords + basura + vg;
    } 
    
    //retorna un nombre de dominio en base a un índice
    function getDomain(index)
    {
        var domains = viewer.getDomains();
        var domain ="";
        if (domains.length>0 && index>=0 && index<domains.length)
        {
            domain = domains[index];
        }
        return domain;
    }
    
    function hideTile(tile)
    {
        if (tile!=null)
        {
            tile.style.display="none";
            if (viewer.getVectorOpacity())
            {
                tile.style.filter="alpha(opacity=0)"; //0-100
                tile.style.opacity="0"; //0-1
            }
        }
    }
    
    //asigna nivel de opacidad a tile
    function setOpacity(tile)
    {
        try
        {
            if (tile!=null)
            {
                var isLoading = tile.getAttribute("loading");
                if (isLoading!=null && isLoading=="false")
                {
                    var opacity = parseFloat(tile.style.opacity);
                    if (opacity<1)
                    {
                        opacity+=0.35;
                        opacity= (opacity>=1) ? 1 : opacity;
                        tile.style.filter="alpha(opacity="+(opacity*100)+")"; //0-100
                        tile.style.opacity=opacity; //0-1
                        
                        if (opacity==1) tile.style.filter="";
                    }
                }
            }
        }catch(e){}
    }
}

