//(C) 2010 Palo TT (palinow at atlas dot cz)

/**
 * @requires OpenLayers/Layer/Grid.js
 * 
 * Class: OpenLayers.Layer.NLCSK
 * 
 * Inherits from:
 *  - <OpenLayers.Layer.Grid>
 */
OpenLayers.Layer.NLCSK = OpenLayers.Class(OpenLayers.Layer.Grid, {

    /** 
     * APIProperty: isBaseLayer
     * {Boolean} NLCSK Layer is always a base layer 
     */    
    isBaseLayer: true,
     
     /**
     * APIProperty: tileSize
     * {<OpenLayers.Size>} Set in the map options to override the default tile
     *                     size for this map.
     */
    tileSize: new OpenLayers.Size(512,512),

    /**
     * Constant: DEFAULT_PARAMS
     * {Object} parameters set by default.
     */
    DEFAULT_PARAMS: {
       },
  
      
    /**
     * Constructor: OpenLayers.Layer.NLCSK
     * 
     * Parameters:
     * name - {String}
     * url - {String} //vynechane
     * params - {Object} 
     * options - {Object} Additional options for the layer. Any of the 
     *     APIProperties listed on this layer, and any layer types it
     *     extends, can be overridden through the options parameter. 
     */
    initialize: function(name,params,options) {
     url="http://lvu.nlcsk.org/arcgiscache/ForestsMaps_DopravnaSiet_SR/Mapa%20lesn%FDch%20a%20pozemn%FDch%20komunik%E1ci%ED/_alllayers/"
     //old version: url="http://wags.nlcsk.org/arcgiscache/Maps_DopravnaSiet_SR/Mapa%20lesn%FDch%20a%20pozemn%FDch%20komunik%E1ci%ED/_alllayers/"
        var newArguments = [];
        newArguments.push(name, url, params, options);
        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
        this.params = (params ? params : {});
        if (params) {
            OpenLayers.Util.applyDefaults(
                           this.params, 
                           this.DEFAULT_PARAMS
                           );
        }
    },

    /**
     * Method: convertHex(number)
     * Convert number to hexadecimal.
     *
     *Parameters:
     *number (decimal)
     */
    convertHex: function (number) {
        var value=arguments[0];
        var radix=16;
        var retval = '';
        var ConvArray = new Array(15);
        ConvArray[0] = '0';
        ConvArray[1] = '1';
        ConvArray[2] = '2';
        ConvArray[3] = '3';
        ConvArray[4] = '4';
        ConvArray[5] = '5';   
        ConvArray[6] = '6';
        ConvArray[7] = '7';
        ConvArray[8] = '8';
        ConvArray[9] = '9';
        ConvArray[10] = 'a';
        ConvArray[11] = 'b';
        ConvArray[12] = 'c';
        ConvArray[13] = 'd';
        ConvArray[14] = 'e';
        ConvArray[15] = 'f';
        var intnum;
        var tmpnum;
        var i = 0;

       intnum = parseInt(value,10);
       if (isNaN(intnum)){
           retval = 'NaN';
       }else{
          while (intnum > 0.9){
              i++;
              tmpnum = intnum;
              // cancatinate return string with new digit:
              retval = ConvArray[tmpnum % radix] + retval;  
              intnum = Math.floor(tmpnum / radix);
              if (i > 100){
                 // break infinite loops
                 retval = 'NaN';
                 break;
              }
           }
        }

     retval = "0000" + retval;
     retval = retval.substr(retval.length-4);
     return retval;
     
     },

     
     /**
     * Method: SourceTileNum()
     * 
     *
     */

      SourceTileNum: function () {
        var zoom=this.map.getZoom();
        var TilNum = new Array();

         
         if (zoom==2)
         {
         TilNum[0]=24440; 
         TilNum[1]=25862; 
         }

 
         if (zoom==1)
         {
         TilNum[0]=9776; 
         TilNum[1]=10344;
         }


         if (zoom==0)
         {
         TilNum[0]=122;
         TilNum[1]=129;
         }
 
         return TilNum;

     },
     
 

    /**
     * Method: getURL
     * 
     * Parameters:
     * bounds - {<OpenLayers.Bounds>} 
     * 
     * Returns:
     * {String} A string with the layer's url and parameters and also the 
     *          passed-in bounds and appropriate tile size specified as 
     *          parameters
     */
    getURL: function (bounds) {
        var TileNum = this.SourceTileNum()     
        var TileNumX=TileNum[0];
        var TileNumY=TileNum[1];

        var extent = this.map.getMaxExtent();
        var resolution = this.map.getResolution();

        var tileX = (((bounds.right-(bounds.right-bounds.left)/2)) - (extent.left));
        tileX=Math.ceil(tileX/(bounds.left-bounds.right)*-1)-1;
        tileX=this.convertHex(TileNumX+tileX);
        
        var tileY = (((bounds.bottom-(bounds.bottom-bounds.top)/2)) - (extent.bottom));
        tileY=Math.ceil(tileY/(bounds.top-bounds.bottom))-1;
        tileY=this.convertHex(TileNumY-tileY);
        
        var zoom=this.map.getZoom();       
        if (zoom==2) LNum = "L08";
        if (zoom==1) LNum = "L07";
        if (zoom==0) LNum = "L01";
       
        var turl = this.url + LNum + "/R0000" + tileY + "/C0000" + tileX + ".png" 
        //alert(tileY + " " + tileX + " " + turl);
        return turl;

    },


    /**
     * Method: addTile
     * 
     * Parameters:
     * bounds - {<OpenLayers.Bounds>}
     * position - {<OpenLayers.Pixel>}
     * 
     * Returns:
     * {<OpenLayers.Tile.Image>}
     */    
    addTile:function(bounds,position) {
        //alert(bounds);
        var url = this.getURL(bounds);
        return new OpenLayers.Tile.Image(this, position, bounds, url, this.tileSize);
    },

    /**
     * Method: initGriddedTiles
     */    
    initGriddedTiles:function(bounds) {

        var zoom=this.map.getZoom();

        if (zoom==0) {
         var options = {maxExtent: new OpenLayers.Bounds(-646043,-1521447,-104175,-979579)};
         } 

       
        if (zoom==1) {
           var options = {maxExtent: new OpenLayers.Bounds(-591693,-1335342,-164964,-1132138)};
           } 

        if (zoom==2) {
           var options = {maxExtent: new OpenLayers.Bounds(-591677,-1336014.5,-164961,-1131461.8)};
           } 




        //OpenLayers.Util.extend(this, options);
        this.addOptions(options);
        //alert(this.map.getMaxExtent());





        // work out mininum number of rows and columns; this is the number of
        // tiles required to cover the viewport plus at least one for panning

        var viewSize = this.map.getSize();
        var minRows = Math.ceil(viewSize.h/this.tileSize.h) + 
                      Math.max(1, 2 * this.buffer);
        var minCols = Math.ceil(viewSize.w/this.tileSize.w) +
                      Math.max(1, 2 * this.buffer);
        
        var extent = this.map.getMaxExtent();
        var resolution = this.map.getResolution();
        var tilelon = resolution * this.tileSize.w;
        var tilelat = resolution * this.tileSize.h;
        
        var offsetlon = bounds.left - extent.left;
        var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
        var tilecolremain = offsetlon/tilelon - tilecol;
        var tileoffsetx = -tilecolremain * this.tileSize.w;
        var tileoffsetlon = extent.left + tilecol * tilelon;
        
        var offsetlat = bounds.top - (extent.bottom + tilelat);  
        var tilerow = Math.ceil(offsetlat/tilelat) + this.buffer;
        var tilerowremain = tilerow - offsetlat/tilelat;
        var tileoffsety = -tilerowremain * this.tileSize.h;
        var tileoffsetlat = extent.bottom + tilerow * tilelat;
        
        tileoffsetx = Math.round(tileoffsetx); // heaven help us
        tileoffsety = Math.round(tileoffsety);

        this.origin = new OpenLayers.Pixel(tileoffsetx, tileoffsety);

        var startX = tileoffsetx; 
        var startLon = tileoffsetlon;

        var rowidx = 0;
    
        do {
            var row = this.grid[rowidx++];
            if (!row) {
                row = [];
                this.grid.push(row);
            }

            tileoffsetlon = startLon;
            tileoffsetx = startX;
            var colidx = 0;
 
            do {
                var tileBounds = 
                    new OpenLayers.Bounds(tileoffsetlon, 
                                          tileoffsetlat, 
                                          tileoffsetlon + tilelon,
                                          tileoffsetlat + tilelat);

                var x = tileoffsetx;
                x -= parseInt(this.map.layerContainerDiv.style.left);

                var y = tileoffsety;
                y -= parseInt(this.map.layerContainerDiv.style.top);

                var px = new OpenLayers.Pixel(x, y);
                var tile = row[colidx++];
                if (!tile) {
                    tile = this.addTile(tileBounds, px);
                    this.addTileMonitoringHooks(tile);
                    row.push(tile);
                } else {
                    tile.moveTo(tileBounds, px, false);
                }
     
                tileoffsetlon += tilelon;       
                tileoffsetx += this.tileSize.w;
            } while ((tileoffsetlon <= bounds.right + tilelon * this.buffer)
                     || colidx < minCols)  
             
            tileoffsetlat -= tilelat;
            tileoffsety += this.tileSize.h;
        } while((tileoffsetlat >= bounds.bottom - tilelat * this.buffer)
                || rowidx < minRows)
        
        //shave off exceess rows and colums
        this.removeExcessTiles(rowidx, colidx);

        //now actually draw the tiles
        this.spiralTileLoad();

    },
   
    CLASS_NAME: "OpenLayers.Layer.NLCSK"
});

