
var gMapCoords = window.gMapCoords = function(map) {
    this.map = map;
}

gMapCoords.prototype = {
    consar : new Array(
        -85051128,-83979259,-82676284,-81093213,-79171334,-76840816,-74019543
        ,-70612614,-66513260,-61606396,-55776579,-48922499,-40979898,-31952162
        ,-21943045,-11178401,0,11178401,21943045,31952162,40979898,48922499
        ,55776579,61606396,66513260,70612614,74019543,76840816,79171334
        ,81093213,82676284,83979259,85051128
    ),
    
    coords : [],
    
    //первая часть — само преобразовании координат в деление, название функций и их содержимое взято с викимапии
    getdatakvname : function (x, y, curzoomkv) {
        var xdel = 0
         ,  ydel = 0
         , xline = 0
         , yline = 0
         , x1 = -180000000
         , x2 = 180000000
         , y1 = -85051128
         , y2 = 85051128
         , y1cons = 0
         , y2cons = 32
         , yconsdel = 0
         , n = 0
         , z = curzoomkv-1
         ;
        while(z >= 0) {
            xdel = Math.round((x1+x2)/2);
            if(n < 4) {
                yconsdel = (y1cons + y2cons)/2; 
                ydel = this.consar[yconsdel];
            } else  {
                ydel = Math.round((y1+y2)/2);
            }
            if(x <= xdel) {
                x2 = xdel; 
                xline = xline * 2;
            }
            else {
                x1 = xdel + 1;
                xline = xline * 2 + 1;
            }
            if(y <= ydel) {
                y2 = ydel; 
                y2cons = yconsdel; 
                yline = yline * 2;
            }
            else   {
                y1 = ydel + 1;
                y1cons = yconsdel; 
                yline = yline * 2 + 1;
            }
            z--;
            n++
        }

        var out = new Array();
        out.xline = xline;
        out.yline = yline;
        return out;
    },
    
    cheakpoint : function(x, y, xline, yline, curzoomkv) {
        var xdel = 0
          , ydel = 0
          , x1 = -180000000
          , x2 = 180000000
          , y1 = -85051128
          , y2 = 85051128
          , y1cons = 0
          , y2cons = 32
          , yconsdel = 0
          , n = 0
          , xlinetest = 0
          , ylinetest = 0
          , test = 0
          , z = curzoomkv-1
          ;
          
        while(z >= 0) {
            xdel = Math.round((x1+x2)/2);
            
            if(n < 4){
                yconsdel = (y1cons+y2cons)/2; 
                ydel = this.consar[yconsdel];
            } else  {
                ydel = Math.round((y1+y2)/2);
            }
            
            test = Math.pow(2, z);
            xlinetest = xline & test;
            ylinetest = yline & test;
            if(xlinetest > 0) {
                x1 = xdel+1;
            } else {
                x2 = xdel;
            }
            if(ylinetest > 0){
                y1 = ydel+1;
                y1cons = yconsdel;
            } else {
                y2 = ydel;
                y2cons = yconsdel;
            }
            z--;
            n++
        }
        var out = new Array();
        out.res = ((x>=x1)&&(x<=x2)&&(y>=y1)&&(y<=y2)) ? 1 : 0; 
        
        return {
            res : ((x>=x1)&&(x<=x2)&&(y>=y1)&&(y<=y2)) ? 1 : 0,
            coords : {x1 : x1, x2 : x2, y1: y1, y2: y2}
        }
    },    
    
    getCoords : function() {
        var coords = {};
        var curzoomkv = this.map.getZoom()-1;
        // @todo разобраться с разными зумами карты, чтобы повторно не запрашивались данные
        curzoomkv = curzoomkv >= 6 ? 6 : (curzoomkv <=3 ? 3 : curzoomkv);
        

        var pushCoords = function(c) {
            key = c.x1 + '_' + c.x2 + '_' + c.y1 + '_' + c.y2;
            coords[key] = c;
        }
        
        var bounds = this.map.getBounds();
        bounds_sw = bounds.getSouthWest();
        bounds_ne = bounds.getNorthEast();
        
        var x1point = Math.round(bounds_sw.lng()*1000000);
        var y1point = Math.round(bounds_sw.lat()*1000000);
        var x2point = Math.round(bounds_ne.lng()*1000000);
        var y2point = Math.round(bounds_ne.lat()*1000000);
        
        if(x1point < -180000000){x1point = -180000000}
        if(x2point < -180000000){x2point = -180000000}
        if(x1point > 180000000) {x1point = 180000000}
        if(x2point > 180000000) {x2point = 180000000}
        if(y1point < -85051128) {y1point = -85051128}
        if(y2point < -85051128) {y2point = -85051128}
        if(y1point > 85051128)  {y1point = 85051128}
        if(y2point > 85051128)  {y2point = 85051128}
    
        outar = [];
        outar = this.getdatakvname(x1point, y1point, curzoomkv);
        
        var xline = outar.xline
          , yline = outar.yline
          , maks = Math.pow(2, curzoomkv)-1
          , vlez = 0
          , xsdvig = 0
          , xlinet = xline
          , ylinet = yline
          ;
          
        while (vlez != 1) {
            r = this.cheakpoint(x2point, y1point, xlinet, ylinet, curzoomkv);
            vlez = r.res;
            pushCoords(r.coords);
            xlinet = xlinet+1;
            if(xlinet > maks) {
                xlinet=0
            }
            xsdvig++;
        }

        vlez = 0;
        var ysdvig = 0
          , xlinet = xline
          , ylinet = yline
          ;

        while (vlez != 1) {
            r = this.cheakpoint(x1point, y2point, xlinet, ylinet, curzoomkv);
            vlez = r.res;
            pushCoords(r.coords);
            ylinet = ylinet+1;
            if (ylinet > maks) {
                ylinet = 0;
            }
            ysdvig++;
        }
        
        return coords;
        
        // @todo - generate compressed coords
        
        var temp = ''
          , newtemp = ''
          , ylinesave = yline
          , ysdvigsave = ysdvig
          ;
          
        require_block = {};          
          
        while (xsdvig > 0) {
            while (ysdvig > 0) {
                temp = '0' + this.retcode(xline, yline, curzoomkv);
                var lineleng = 0
                  , newtemp = ''
                  ;
                  
                while (lineleng < temp.length) {
                    newtemp = newtemp + "/" + temp.substring(lineleng, lineleng+3);
                    lineleng = lineleng + 3;
                }
                xml_url = newtemp;
                require_block[temp] = xml_url;

                ysdvig--; 
                yline++;
                if (yline > maks) {
                    yline=0;
                }
            }
            yline = ylinesave;
            ysdvig = ysdvigsave;
            xsdvig--;
            xline++;
            if (xline > maks){
                xline=0;
            }
        }
        
        return require_block;
    },
    
    retcode : function(xline, yline, curzoomkv) {
        var xparam = 0
          , yparam = 0
          , test = 0
          , xlinetest = 0
          , ylinetest = 0
          , line = ''
          , z = curzoomkv-1
          ;
        while(z >= 0) {
            test = Math.pow(2, z);
            xlinetest = xline & test;
            ylinetest = yline & test;
            
            xparam = (xlinetest > 0) ? 1 : 0;
            yparam = (ylinetest > 0) ? 2 : 0;
            
            linepart = xparam + yparam;
            line = line + linepart;
            z--;
        }
        return line;
    }
};
