
//HELPER FUNCTIONS
function parse_snippet(str, variables){
    str = "'" + str + "';";
    str = str.replace(/\[\*/g, "' + variables.");
    str = str.replace(/\*]/g, " + '");
    str = str.replace(/\s\s+/g, "");
    x = eval(str);
    return x;
}


//================================================================================================
// FUNKCJE POMOCNICZE DO GMAP


function load_kml(file){
    var kml = new GGeoXml(file);
    map.addOverlay(kml);
}


function VIcon(file, size){
    size = parseInt(size);
    var icon = new GIcon(G_DEFAULT_ICON);
    with (icon) {
        image = PATH_ICONS + file;
        shadow = PATH_ICONS + "shadow.png";
        iconSize = new GSize(parseInt(32 * size / 100), parseInt(37 * size / 100));
        shadowSize = new GSize(parseInt(51 * size / 100), parseInt(37 * size / 100));
        iconAnchor = new GPoint(parseInt(16 * size / 100), parseInt(37 * size / 100));
        infoWindowAnchor = new GPoint(parseInt(16 * size / 100), 0);
        printImage = PATH_ICONS + file;
        //mozPrintImage
        //printShadow
        //transparent
        //imageMap
        maxHeight = 25;
        //dragCrossImage
        //dragCrossSize
        //dragCrossAnchor
    }
    return icon;
}

function VMarkerOptions(file, size, draggable){
    var mo;
    mo = {
        icon: new VIcon(file, size),
        zIndexProcess: importanceMarkerOrder
    };
    
    if (draggable) {
        mo.draggable = true;
    }
    return mo;
}

function importanceMarkerOrder(marker, b){
    return GOverlay.getZIndex(marker.getPoint().lat()) + marker.importance * 1000000;
}




//GMAP ZOOM LIMITER PLUGIN
GMap2.prototype.zoom_limiter = function(limits){
    if (limits.zoom_min || limits.zoom_max) {
        var mt = this.getMapTypes();
        if (limits.zoom_min) {
            for (var i = 0; i < mt.length; i++) {
                mt[i].getMinimumResolution = function(){
                    return limits.zoom_min;
                };
            }
        }
        if (limits.zoom_max) {
            for (var i = 0; i < mt.length; i++) {
                mt[i].getMaximumResolution = function(){
                    return limits.zoom_max;
                };
            }
        }
    }
    else {
        alert("GMAP ZOOM LIMITER:Brak zadefiniowanych parametrów.");
    }
};

//GMAP.LATLNG_LIMITER_PLUGIN
GMap2.prototype.latlng_limiter = function(limits){
    if (limits.lat_min && limits.lat_max && limits.lng_min && limits.lng_max) {
        GEvent.addListener(this, "move", function(){
            var bound_alert = false;
            var bounds = new GLatLngBounds();
            var center = new GLatLng;
            bounds = this.getBounds();
            center = this.getCenter();
            
            
            lat_center = center.lat();
            lng_center = center.lng();
            lat_min_current = bounds.getSouthWest().lat();
            lng_min_current = bounds.getSouthWest().lng();
            lat_max_current = bounds.getNorthEast().lat();
            lng_max_current = bounds.getNorthEast().lng();
            
            lat_min = limits.lat_min;
            lat_max = limits.lat_max;
            lng_min = limits.lng_min;
            lng_max = limits.lng_max;
            
            lat_offset = 0;
            lng_offset = 0;
            
            if (((lng_max - lng_min) > (lng_max_current - lng_min_current)) && ((lat_max - lat_min) > (lat_max_current - lat_min_current))) {
                if (lng_min_current < lng_min) {
                    lng_offset = lng_min - lng_min_current;
                    bound_alert = true;
                }
                
                if (lng_max_current > lng_max) {
                    lng_offset = lng_max - lng_max_current;
                    bound_alert = true;
                }
                
                if (lat_min_current < lat_min) {
                    lat_offset = lat_min - lat_min_current;
                    bound_alert = true;
                }
                
                if (lat_max_current > lat_max) {
                    lat_offset = lat_max - lat_max_current;
                    bound_alert = true;
                }
            }
            
            if (bound_alert) {
                this.setCenter(new GLatLng(lat_center + lat_offset, lng_center + lng_offset));
            }
        });
        
    }
    else 
        alert("GMAP LATLNG_LIMIITER:Brak zadefiniowanych parametrów.")
}

//GMAP.LATLNG_LIMITER_2 PLUGIN 
GMap2.prototype.latlng_limiter_2 = function(limits){
    if (limits.lat_min && limits.lat_max && limits.lng_min && limits.lng_max) {
        GEvent.addListener(this, "move", function(){
        
            var allowedBounds = new GLatLngBounds(new GLatLng(limits.lat_min, limits.lng_min), new GLatLng(limits.lat_max, limits.lng_max));
            if (allowedBounds.contains(this.getCenter())) {
                return;
            }
            var C = this.getCenter();
            var X = C.lng();
            var Y = C.lat();
            
            var AmaxX = allowedBounds.getNorthEast().lng();
            var AmaxY = allowedBounds.getNorthEast().lat();
            var AminX = allowedBounds.getSouthWest().lng();
            var AminY = allowedBounds.getSouthWest().lat();
            
            if (X < AminX) {
                X = AminX;
            }
            if (X > AmaxX) {
                X = AmaxX;
            }
            if (Y < AminY) {
                Y = AminY;
            }
            if (Y > AmaxY) {
                Y = AmaxY;
            }
            //alert ("Restricting "+Y+" "+X);
            this.setCenter(new GLatLng(Y, X));
        });
        
    }
    else 
        alert("GMAP LATLNG_LIMIITER_2:Brak zadefiniowanych parametrów.")
}

//------------------------------------------------------
// GMAP PLUGINS

//-----------------------------------------
// DISPLAY NAME OF THE CLASS
function mGetObCl(obj){
    if (typeof obj != "object" || obj === null) 
        return false;
    else 
        return /(\w+)\(/.exec(obj.constructor.toString())[1];
}

//---------------------------------------------------
// DEFINING mAdress object
function mAddress(address){
    if (typeof address == "object") {
        this.country = (typeof address.country != "undefined") ? address.country : null;
        this.region = (typeof address.region != "undefined") ? address.region : null;
        this.district = (typeof address.district != "undefined") ? address.district : null;
        this.municipality = (typeof address.municipality != "undefined") ? address.municipality : null;
        this.locality = (typeof address.locality != "undefined") ? address.locality : null;
        this.street = (typeof address.street != "undefined") ? address.street : null;
        this.postcode = (typeof address.postcode != "undefined") ? address.postcode : null;
        this.lat = (typeof address.lat != "undefined") ? address.lat : null;
        this.lng = (typeof address.lng != "undefined") ? address.lng : null;
    }
    else {
        this.country = null;
        this.region = null;
        this.district = null;
        this.municipality = null;
        this.locality = null;
        this.street = null;
        this.postcode = null;
        this.lat = null;
        this.lng = null;
    }
    
    this.rating = 0;
    this.accuracy = 0;
    
    //debuging function
    this.echo = function(){
        var temp = "";
        for (a in this) {
            if (typeof this[a] != "function") {
                temp += a + ": " + ((this[a]) ? this[a] : "") + "\n";
            }
        }
        alert(temp);
    };
    
    this.constructString = function(omit_street){
        var tempS = "";
        if (this.street && !omit_street) 
            tempS = "ul." + this.street + ", ";
        if (this.locality) 
            tempS += this.locality + ", ";
        // Postal code doesn't seem to work in Poland
        //if (this.postcode) 
        //    tempS += this.postcode;
        //if (this.region && !this.postcode) 
        if (this.region) 
            tempS += this.region;
        return tempS;
    };
}


//======================================================================================================
// FUNKCJE GEOCODINGU
//======================================================================================================
// !!!!!!!!! WYMAGAJĄ GRUNTOWNEJ PRZEBUDOWY I UPROSZCZENIA
// DO ZROBIENIA W PRZYSZŁOŚCI, PUKI CO DZIAŁA
//


// Method for exact geocoding based on special rating
GClientGeocoder.prototype.mGeocode = function(address, callback){

    //DEBUG=======================================
    if (DEBUG) 
        alert("Execution of mGeocode started!");
    //============================================
    
    var result;
    var current_max_index = null;
    var current_max_points = 0;
    var success = false;
    var geocoder = this;
    var toomanyqueries = false;
    var c_status = 0;
    
    if (mGetObCl(address) != "mAddress") {
        alert("parameter for GClientGeocoder.mGeocode has to be mAddress object type!");
    }
    else {
        if (!(address.lat) || ((address.lat)) == 0 || !(address.lng) || ((address.lng)) == 0) {
            if (address.locality) {
            
                //DEBUG=======================================
                if (DEBUG) 
                    alert("Calling mGetLocations from mGeocode!");
                //============================================
                
                this.mGetLocations(address.constructString(), function(status, locations){
                
                    //DEBUG=======================================
                    if (DEBUG) 
                        alert("Recieved callback from mGetLocations!");
                    //============================================
                    
                    switch (status) {
                        case G_GEO_SUCCESS:{
                            for (var i = 0; i < locations.length; i++) {
                                if (locations[i].region) {
                                    if (locations[i].region.toLowerCase() == address.region.toLowerCase()) {
                                        if (locations[i].locality.toLowerCase() == address.locality.toLowerCase()) {
                                            locations[i].rating = 1000 + Number(locations[i].accuracy);
                                            success = true;
                                        }
                                    }
                                }
                            }
                            if (success) {
                                for (var i = 0; i < locations.length; i++) {
                                    if (Number(locations[i].rating) > Number(current_max_points)) {
                                        current_max_index = i;
                                    }
                                }
                                result = locations[current_max_index];
                                
                                
                                //DEBUG=======================================
                                if (DEBUG) 
                                    alert("Calling mGeocodeMunicipality!");
                                //============================================
                                
                                geocoder.mGeocodeMunicipality(new GLatLng(result.lat, result.lng), function(mun, stat_mun){
                                
                                    //DEBUG=======================================
                                    if (DEBUG) {
                                        alert("Callback from mGeocodeMunicipality! mun: " + mun + " stat_mun: " + stat_mun);
										result.echo();
                                    }
                                    //============================================
                                    
                                    if (stat_mun == 1) {
                                        if (!mun) {
                                            result.municipality = result.locality;
                                        }
                                        else {
                                            result.municipality = mun;
                                        }
                                        c_status = 1;
                                        
                                        //DEBUG=======================================
                                        if (DEBUG) {
                                            alert("hmmmmmmmm");
                                            result.echo();
                                        }
                                        //============================================
                                        
                                        callback(c_status, result);
                                    }
                                    else 
                                        if (stat_mun == -1) {
                                            c_status = -1;
                                            callback(c_status, result);
                                        }
                                        else 
                                            if (stat_mun == -2) {
                                                c_status = -2;
                                                callback(c_status, result);
                                            }
                                    
                                    
                                });
                            }
                            else 
                                if (address.street) {
                                    var address2 = address;
                                    address2.street = null;
                                    geocoder.mGeocode(address2, callback);
                                }
                                else {
                                    callback(-1, 0);
                                }
                            break;
                        }
                        case G_GEO_TOO_MANY_QUERIES:
                            toomanyqueries = true;
                            c_status = -2;
                            break;
                        case G_GEO_UNKNOWN_ADDRESS:
                            c_status = -1;
                            break;
                        case G_GEO_MISSING_QUERY:
                            c_status = -1;
                            break;
                        case G_GEO_SERVER_ERROR:
                            c_status = -1;
                            break;
                        case G_GEO_UNAVAILABLE_ADDRESS:
                            c_status = -1;
                            break;
                        case G_GEO_BAD_KEY:
                            c_status = -1;
                            break;
                        default:
                            alert("FATAL ERROR, something is wrong, the status code is missing.");
                    }
                    
                    if (c_status == -1) {
                        callback(c_status, "");
                    }
                    else 
                        if (c_status == -2) {
                            callback(c_status, "");
                        }
                });
                
            }
            else {
                alert("Missing data");
            }
        }
        else {
            geocoder.mGetLocations(new GLatLng(address.lat, address.lng), function(code, locations){
                var best;
                var max_accuracy = 0;
                for (i in locations) {
                    if (Number(locations[i].accuracy) > max_accuracy) {
                        max_accuracy = locations[i].accuracy;
                        best = i;
                    }
                }
                result = locations[best];
                geocoder.mGeocodeMunicipality(new GLatLng(address.lat, address.lng), function(mun, stat_mun, distr){
                    if (stat_mun == 1) {
                        if (!mun) {
                            result.municipality = result.locality;
                        }
                        else {
                            result.municipality = mun;
                            result.district = distr;
                        }
                        c_status = 1;
                        callback(c_status, result);
                    }
                    else 
                        if (stat_mun == -1) {
                            c_status = -1;
                            callback(c_status, result);
                        }
                        else 
                            if (stat_mun == -2) {
                                c_status = -2;
                                callback(c_status, result);
                            }
                });
                
                
                
                
            });
            
            
        }
        
    }
    
};


// Method returning municipality for given LatLng
GClientGeocoder.prototype.mGeocodeMunicipality = function(latlng, callback){
    var muntemp = "";
    var district = "";
	var status=0;
    this.mGetLocations(latlng, function(code, locations){
        if (code == 200) {
            for (var i = 0; i < locations.length; i++) {
                status = 1;
                if (locations[i].municipality) {
                    muntemp = locations[i].municipality;
                    district = locations[i].district;
                    break;
                }
            }
            callback(muntemp, status, district);
        }
        else 
            if (code == G_GEO_TOO_MANY_QUERIES) {
                callback(0, -2);
            }
            else {
                callback(0, -1)
            }
    });
    
};



// Method for getting locations in mAddress object type
GClientGeocoder.prototype.mGetLocations = function(query, callback){
    this.getLocations(query, function(results){
        geocoder_result = results;
        var locations = [];
        var code = results.Status.code;
        if (typeof results.Placemark != "undefined") {
            for (i = 0; i < results.Placemark.length; i++) {
                var address = new mAddress();
                result = results.Placemark[i];
                if (typeof result.AddressDetails.Country != 'undefined') {
                    address.country = result.AddressDetails.Country.CountryName;
                    if (typeof result.AddressDetails.Country.AdministrativeArea != 'undefined') {
                        address.region = result.AddressDetails.Country.AdministrativeArea.AdministrativeAreaName;
                        if (typeof result.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea != 'undefined') {
                            address.district = result.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.SubAdministrativeAreaName;
                            if (typeof result.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.AddressLine != 'undefined') 
                                address.municipality = result.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.AddressLine[0];
                            if (typeof result.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality != 'undefined') {
                                address.locality = result.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.LocalityName;
                                if (typeof result.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare != 'undefined') 
                                    address.street = result.AddressDetails.Country.AdministrativeArea.SubAdministrativeArea.Locality.Thoroughfare.ThoroughfareName;
                            }
                        }
                    }
                }
                address.accuracy = result.AddressDetails.Accuracy;
                address.lat = result.Point.coordinates[1];
                address.lng = result.Point.coordinates[0];
                locations.push(address);
            } // end for
            //EXECUTING CALLBACK FUNCTION
        }
        
        callback(code, locations);
	
    }); //end getLocations
}; //end mGetLocations

