PM.Locales.list['Add location description'] = 'Dodaj opis lokacije';
PM.Locales.list['Add Point of Interest'] = 'Dodaj tocku interesa';
PM.Locales.list['Add WMS layers'] = 'Dodaj WMS slojeva';
PM.Locales.list['Administrative Entity'] = 'Administrativna entitetska';
PM.Locales.list['Altitude'] = 'Visina';
PM.Locales.list['Apply on Layer'] = 'Aktivna karta';
PM.Locales.list['Area'] = 'Područje';
PM.Locales.list['Auto Identify'] = 'Alat Savjet';
PM.Locales.list['Available Layers'] = 'Dostupani slojevi  ';
PM.Locales.list['Back'] = 'Nazad';
PM.Locales.list['BACK'] = 'NAZAD';
PM.Locales.list['Below exiting layers'] = 'Ispod slojeva izlaska';
PM.Locales.list['Capital'] = 'Capital';
PM.Locales.list['cat_admin'] = 'Administrativni del';
PM.Locales.list['Category Info'] = 'Kategorija Info';
PM.Locales.list['cat_infrastructure'] = 'Infrastrukture';
PM.Locales.list['cat_nature'] = 'Priroda-prostornih podataka';
PM.Locales.list['cat_raster'] = 'Rasterskih podataka';
PM.Locales.list['cat_satimages'] = 'Satelitske snimke';
PM.Locales.list['cat_srtm'] = 'SRTM podataka';
PM.Locales.list['Cities'] = 'Mesta';
PM.Locales.list['City'] = 'City';
PM.Locales.list['Clear'] = 'Ocistiti';
PM.Locales.list['Coastlines'] = 'Coastlines';
PM.Locales.list['Collapse'] = 'Kolaps';
PM.Locales.list['Commune'] = 'Commune';
PM.Locales.list['Communes'] = 'Communes';
PM.Locales.list['Copy Path'] = 'Kopiraj link';
PM.Locales.list['Countries'] = 'Države';
PM.Locales.list['Country'] = 'Country';
PM.Locales.list['Create PDF Document'] = 'Kreiraj PDF Dokument';
PM.Locales.list['Create Print Page'] = 'Napravite Ispiši stranicu';
PM.Locales.list['Description'] = 'Opis';
PM.Locales.list['Digital Elevation Model'] = 'Digital Elevation Model';
PM.Locales.list['Digital Terrain Model'] = 'Digital Terrain Model';
PM.Locales.list['Digitize'] = 'Digitalizirati';
PM.Locales.list['digitize_help'] = ' Kraj mjerenja - dvostruki klik <br />Brisanje zadnje tocke - DEL tipka';
PM.Locales.list['digitize_over'] = 'Novu stranu preklapa drugu stranu poligona. \\nA poligon ne može sama preklapati.';
PM.Locales.list['Display Limit'] = 'Prikaz graničnim';
PM.Locales.list['Download'] = 'Download';
PM.Locales.list['Expand'] = 'Proširiti';
PM.Locales.list['Export result as'] = 'Izvoz rezultat kao';
PM.Locales.list['Forward'] = 'Napred';
PM.Locales.list['Geo-data source'] = 'Izvor geo-podaca';
PM.Locales.list['Help'] = 'Pomo&#263;';
PM.Locales.list['Hide Legend'] = 'Sakrij Legenda';
PM.Locales.list['Hydrography'] = 'Hydrography';
PM.Locales.list['ID'] = 'ID';
PM.Locales.list['Identify'] = 'Info';
PM.Locales.list['Images'] = 'Slike';
PM.Locales.list['Info'] = 'Info';
PM.Locales.list['Infrastructure'] = 'Infrastructure';
PM.Locales.list['ISO Code'] = 'ISO Code';
PM.Locales.list['Lakes'] = 'Lakes';
PM.Locales.list['Large'] = 'Large';
PM.Locales.list['Layer'] = 'Slojevi';
PM.Locales.list['Layer Info'] = 'Slojevi info';
PM.Locales.list['Layers'] = 'Slojevi';
PM.Locales.list['Layers Off'] = 'Slojevi isključi';
PM.Locales.list['Layers On'] = 'Slojevi uključi';
PM.Locales.list['Layer transparency'] = 'Providnost slojeva';
PM.Locales.list['Legend'] = 'Legenda';
PM.Locales.list['Length'] = 'Dužina';
PM.Locales.list['Link'] = 'Link';
PM.Locales.list['Link on detail'] = 'Link na detalj';
PM.Locales.list['Link to current map'] = 'Link';
PM.Locales.list['Load link in current window'] = 'Link u trenutnom prozoru';
PM.Locales.list['Load WMS Service'] = 'Opterećenje WMS Servis';
PM.Locales.list['Map Resolution for Download'] = 'Rezolucija karte za preuzimanje';
PM.Locales.list['MapServer PHP/MapScript Framework'] = 'MapServer PHP/MapScript Framework';
PM.Locales.list['Map window size'] = 'Veličina karte';
PM.Locales.list['Measure'] = 'Mjerenje';
PM.Locales.list['Medium'] = 'Medium';
PM.Locales.list['Name'] = 'Ime';
PM.Locales.list['Navigation'] = 'Navigacija';
PM.Locales.list['NEXT'] = 'Sljedeći';
PM.Locales.list['No data'] = 'Ni podacov';
PM.Locales.list['No records found'] = 'Bez zadetka';
PM.Locales.list['On map click'] = 'Klik na karti';
PM.Locales.list['On top of exiting layers'] = 'Na vrhu izlaza slojeva';
PM.Locales.list['Pan'] = 'Pomicanje';
PM.Locales.list['Population'] = 'Population';
PM.Locales.list['Print'] = 'Iscrtaj';
PM.Locales.list['Print Map'] = 'Printaj kartu';
PM.Locales.list['Print Settings'] = 'Postavke iscrtavanja';
PM.Locales.list['Print Title'] = 'Naslov izrisa';
PM.Locales.list['Print View'] = 'Pregled iscrtavanja';
PM.Locales.list['Query Results'] = 'Query Results';
PM.Locales.list['Railroad'] = 'Railroad';
PM.Locales.list['records exceeded'] = ' records exceeded. Subsequent records not displayed.';
PM.Locales.list['Refresh Map'] = 'Refresh Map';
PM.Locales.list['Restrict Search to Map Extent'] = 'Restrict Search to Map Extent';
PM.Locales.list['Result'] = 'Result';
PM.Locales.list['Rivers'] = 'Rivers';
PM.Locales.list['Roads'] = 'Roads';
PM.Locales.list['Run Search'] = 'Run Search';
PM.Locales.list['Scale'] = 'Mjerilo';
PM.Locales.list['Search'] = 'Traži';
PM.Locales.list['Search for'] = 'Pretrazivanje';
PM.Locales.list['Search Image'] = 'Search Image';
PM.Locales.list['Search results for layer'] = 'Search results for layer';
PM.Locales.list['Segment'] = 'Segment';
PM.Locales.list['Select'] = 'Multi-izbornik';
PM.Locales.list['Select Image Format'] = 'Select Image Format';
PM.Locales.list['Select Layers'] = 'Select Layers';
PM.Locales.list['Select Projection'] = 'Select Projection';
PM.Locales.list['Select/Search limit of'] = 'Select/Search limit of';
PM.Locales.list['Set Scale'] = 'Set Scale';
PM.Locales.list['Settlements'] = 'Settlements';
PM.Locales.list['Show'] = 'Show';
PM.Locales.list['Show Layers'] = 'Show Layers';
PM.Locales.list['Show Legend'] = 'Show Legend';
PM.Locales.list['Site'] = 'Site';
PM.Locales.list['Slope'] = 'Slope';
PM.Locales.list['Small'] = 'Small';
PM.Locales.list['Start Search'] = 'Start Search';
PM.Locales.list['Tools'] = 'Oruđe';
PM.Locales.list['Total'] = 'Ukupno';
PM.Locales.list['Transparency'] = 'Transparency';
PM.Locales.list['Transparent'] = 'Transparentan';
PM.Locales.list['Type'] = 'Type';
PM.Locales.list['Update'] = 'Update';
PM.Locales.list['Urban Area'] = 'Urban Areas';
PM.Locales.list['Water'] = 'Water bodies';
PM.Locales.list['With Overview Map'] = 'With Overview Map';
PM.Locales.list['WMS Service'] = 'WMS Service';
PM.Locales.list['Zoom'] = 'Zoom';
PM.Locales.list['Zoom in'] = 'Priblizi';
PM.Locales.list['Zoom out'] = 'Udalji';
PM.Locales.list['Zoom to All Features Found'] = 'Zoom to All Features Found';
PM.Locales.list['Zoom To Full Extent'] = 'Pogled na pocetnu kartu';
PM.Locales.list['Zoom To Layer'] = 'Zoom To Layer';
PM.Locales.list['Zoom To Selected'] = 'Pogled na izbor';
PM.Locales.list['Zoom to Selected Features'] = 'Zoom to Selected Features';
PM.Locales.list['Drawing'] = 'Nacrtaj';
PM.Locales.list['QueryEditor'] = 'SQL pretrazivanje';
PM.Locales.list['katasterSearch'] = 'Pretrazivanje katastra';
PM.Locales.list['3dview'] = '3D';
PM.Locales.list['Advanced'] = 'napredno';
PM.Locales.list['Add comment'] = 'Dodaj komentar';
PM.Locales.list['polygon'] = 'Poligon';
PM.Locales.list['IdentifyAdd'] = 'Dokument';
PM.Locales.list['identifyKataster'] = 'Katastar info';
PM.Locales.list['Iskanje po katastru'] = 'Tra&#382;i po katastru';
PM.Locales.list['Point'] = 'To&#269;ka';
PM.Locales.list['Line'] = 'Linija';
PM.Locales.list['Annotation'] = 'Tekst';
PM.Locales.list['ImageToolTip'] = 'Slika';
PM.Locales.list['Deselect'] = 'Deselektirati';
/******************************************************************************
 *
 * Purpose: functions for query result export
 * Author:  Armin Burger
 *
 ******************************************************************************
 *
 * Copyright (c) 2003-2009 Armin Burger
 *
 * This file is part of p.mapper.
 *
 * p.mapper is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * p.mapper is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

 
/**
 * Export query results in various file formats
 */

$.extend(PM.Plugin, 
{
    Export:
    {
        /** 
         * run PHP export functions via AJAX 
         */ 
        exportQueryResult: function(format) {
            $('#exportLinkDL').hide();
            // PDF or (XLS + IE) --> open in new window 
            var target = (format == 'PDF' || (format == 'XLS' && $.browser.msie)) ? ' target="_blank"' : '';
            $.ajax({
                url: PM_PLUGIN_LOCATION + '/export/x_export.php?' + SID + '&format=Export' + format,
                dataType: "json",
                success: function(response){
                    $('#exportLinkDL').html('<a href="' + response.expFileLocation + '" ' + target + '>' + _p('Download')+ '</a>').show();
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    if (window.console) console.log(errorThrown);
                } 
            });  
        },

        /** 
         * Add controls to result display (called from pmjson.js) 
         */ 
        addToQueryResultHtml: function() {

            var pmExport = '';
            try {

                pmExport = [];
                var pluginConfig = PM.ini.pluginsConfig['export']; 
                if (typeof(pluginConfig.formats) != 'undefined') {
                    if (typeof(pluginConfig.formats) == 'object') {
                        pmExport = pluginConfig.formats;
                    } else {
                        pmExport = [pluginConfig.formats];
                    }
                }
            } catch(e) {
                var pmExport = ['XLS', 'CSV', 'PDF'];
            }
            
            var html = "";
            if (pmExport.length > 0) {
                html += '<div id="selectexport">';
                html += '<div style="display:block; padding-bottom:4px">' + _p('Export result as') + '</div>';
            
                $.each(pmExport, function() {
                    html += '<div class="exportFormat"><input type="radio" name="exportformat" onclick="PM.Plugin.Export.exportQueryResult(' + '\'' + this + '\')" /><img src="plugins/export/images/' + this.toLowerCase() + '.gif" title="' + this + '" alt="' + this + '"/></div>';
                });
            
                html += '<div style="height:30px"><div id="exportLinkDL"></div></div>';
                html += '</div>';
            }
            
            return html;
        }
    }
});

$.merge(PM.Custom.queryResultAddList, ['PM.Plugin.Export.addToQueryResultHtml()']);



/*
JavaScript Scalebar for MapServer (scalebar.js)

Copyright (c) 2005 Tim Schaub of CommEn Space (http://www.commenspace.org)

This is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of the License, or (at
your option) any later version.

This software is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this software; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

v1.3.1 - removed a typo that affected .sbBar with borders (thanks jlivni)
       - scalebar is now centered on .sbWrapper div by default, more css control
       - reduced likelihood of displaying very large numbers
       - added condition to deal with @import styles (thanks dokai)

*/


/******************************************************************

  With some modifications by Armin Burger for use in p.mapper

 ******************************************************************/

/**
 * Initialize function for p.mapper
 * by Armin Burger
 */
$.extend(PM.Plugin,
{
    ScaleBar: 
    {
        sB: new ScaleBar(1),
        init: function() {
            if (typeof(PM.scaleBarOptions)!="undefined") {
                var opt = PM.scaleBarOptions;
                this.sB.divisions = opt.divisions;
                this.sB.subdivisions = opt.subdivisions;
                this.sB.resolution = opt.resolution;
                this.sB.minWidth = opt.minWidth;
                this.sB.maxWidth = opt.maxWidth;
                this.sB.abbreviateLabel = opt.abbreviateLabel;
            }
            this.sB.place('scalebar');
            
            $("#scalebar").showv();
            this.sB.update(PM.s1);
            
            // Bind scalebar update to map update event
            PM.Map.bindOnMapRefresh(function(e){
                PM.Plugin.ScaleBar.sB.update(PM.scale);
            });
        }
    }
});


function ScaleBar(scaleDenominator) {
    // default properties
    // may be modified after construction
    // if modified after ScaleBar.place(), use ScaleBar.update()
    this.scaleDenominator = (scaleDenominator == null) ? 1 : scaleDenominator;
    this.displaySystem = 'metric'; // metric or english supported
    this.minWidth = 100; // pixels
    this.maxWidth = 200; // pixels
    this.divisions = 2;
    this.subdivisions = 2;
    this.showMinorMeasures = false;
    this.abbreviateLabel = true;
    this.singleLine = false;
    this.resolution = 96; // dpi
    this.align = 'center'; // left, center, or right supported
    // create scalebar elements
    this.container = document.createElement('div');
    this.container.className = 'sbWrapper';
    this.labelContainer = document.createElement('div');
    this.labelContainer.className = 'sbUnitsContainer';
    this.labelContainer.style.position = 'absolute';
    this.graphicsContainer = document.createElement('div');
    this.graphicsContainer.style.position = 'absolute';
    this.graphicsContainer.className = 'sbGraphicsContainer';
    this.numbersContainer = document.createElement('div');
    this.numbersContainer.style.position = 'absolute';
    this.numbersContainer.className = 'sbNumbersContainer';
    // private functions
    // put in some markers and bar pieces so style attributes can be grabbed
    // this is a solution for Safari support
    var markerMajor = document.createElement('div');
    markerMajor.className = 'sbMarkerMajor';
    this.graphicsContainer.appendChild(markerMajor);
    var markerMinor = document.createElement('div');
    markerMinor.className = 'sbMarkerMinor';
    this.graphicsContainer.appendChild(markerMinor);
    var barPiece = document.createElement('div');
    barPiece.className = 'sbBar';
    this.graphicsContainer.appendChild(barPiece);
    var barPieceAlt = document.createElement('div');
    barPieceAlt.className = 'sbBarAlt';
    this.graphicsContainer.appendChild(barPieceAlt);
}
ScaleBar.prototype.update = function(scaleDenominator) {
    if(scaleDenominator != null) {
        this.scaleDenominator = scaleDenominator;
    };
    // local functions (and object constructors)
    function HandsomeNumber(smallUglyNumber, bigUglyNumber, sigFigs) {
        var sigFigs = (sigFigs == null) ? 10 : sigFigs;
        var bestScore = Number.POSITIVE_INFINITY;
        var bestTieBreaker = Number.POSITIVE_INFINITY;
        // if all else fails, return a small ugly number
        var handsomeValue = smallUglyNumber;
        var handsomeNumDec = 3;
        // try the first three comely multiplicands (in order of comliness)
        for(var halvingExp = 0; halvingExp < 3; ++halvingExp) {
            var comelyMultiplicand = Math.pow(2, (-1 * halvingExp));
            var maxTensExp = Math.floor(Math.log(bigUglyNumber / comelyMultiplicand) / Math.LN10);
            for(var tensExp = maxTensExp; tensExp > (maxTensExp - sigFigs + 1); --tensExp) {
                var numDec = Math.max(halvingExp - tensExp, 0);
                var testMultiplicand = comelyMultiplicand * Math.pow(10, tensExp);
                // check if there is an integer multiple of testMultiplicand between smallUglyNumber and bigUglyNumber
                if((testMultiplicand * Math.floor(bigUglyNumber / testMultiplicand)) >= smallUglyNumber) {
                    // check if smallUglyNumber is an integer multiple of testMultiplicand
                    if(smallUglyNumber % testMultiplicand == 0) {
                        var testMultiplier = smallUglyNumber / testMultiplicand;
                    }
                    // otherwise go for the smallest integer multiple between small and big
                    else {
                        var testMultiplier = Math.floor(smallUglyNumber / testMultiplicand) + 1;
                    }
                    // test against the best (lower == better)
                    var testScore = testMultiplier + (2 * halvingExp);
                    var testTieBreaker = (tensExp < 0) ? (Math.abs(tensExp) + 1) : tensExp;
                    if((testScore < bestScore) || ((testScore == bestScore) && (testTieBreaker < bestTieBreaker))) {
                        bestScore = testScore;
                        bestTieBreaker = testTieBreaker;
                        handsomeValue = (testMultiplicand * testMultiplier).toFixed(numDec);
                        handsomeNumDec = numDec;
                    }
                }
            }
        }
        this.value = handsomeValue;
        this.score = bestScore;
        this.tieBreaker = bestTieBreaker;
        this.numDec = handsomeNumDec;
    };
    HandsomeNumber.prototype.toString = function() {
        return this.value.toString();
    };
    HandsomeNumber.prototype.valueOf = function() {
        return this.value;
    };
    function styleValue(aSelector, styleKey) {
        // returns an integer value associated with a particular selector and key
        // given a stylesheet with .someSelector {border: 2px solid red}
        // styleValue('.someSelector', 'borderWidth') returns 2
        var aValue = 0;
        if(document.styleSheets) {
            for(var sheetIndex = document.styleSheets.length - 1; sheetIndex >= 0; --sheetIndex) {
                var aSheet = document.styleSheets[sheetIndex];
                
                if(!aSheet.disabled) {
                    var allRules;
                    if(typeof(aSheet.cssRules) == 'undefined') {
                        if(typeof(aSheet.rules) == 'undefined') {
                            // can't get rules, assume zero
                            return 0;
                        }
                        else {
                            allRules = aSheet.rules;
                        }
                    }
                    else {
                        allRules = aSheet.cssRules;
                    }
                    //===  p.mapper: inserted try{} due to errors in Google Chrome ===
                    try {
                        for(var ruleIndex = 0; ruleIndex < allRules.length; ++ruleIndex) {
                            var aRule = allRules[ruleIndex];
                            if(aRule.selectorText && (aRule.selectorText.toLowerCase() == aSelector.toLowerCase())) {
                                if(aRule.style[styleKey] != '') {
                                    aValue = parseInt(aRule.style[styleKey]);
                                }
                            }
                        }
                    } catch(e) {
                        
                    }
                }
            }
        }
        // if the styleKey was not found, the equivalent value is zero
        return aValue ? aValue : 0;
    };
    function formatNumber(aNumber, numDecimals) {
        numDecimals = (numDecimals) ? numDecimals : 0;
        var formattedInteger = '' + Math.round(aNumber);
        var thousandsPattern = /(-?[0-9]+)([0-9]{3})/;
        while(thousandsPattern.test(formattedInteger)) {
            formattedInteger = formattedInteger.replace(thousandsPattern, '$1,$2');
        }
        if(numDecimals > 0) {
            var formattedDecimal = Math.floor(Math.pow(10, numDecimals) * (aNumber - Math.round(aNumber)));
            if(formattedDecimal == 0) {
                return formattedInteger;
            }
            else {
                return formattedInteger + '.' + formattedDecimal;
            }
        }
        else {
            return formattedInteger;
        }
    };
    // update the container title (for displaying scale as a tooltip)
    this.container.title = 'scale 1:' + formatNumber(this.scaleDenominator);
    // measurementProperties holds display units, abbreviations,
    // and conversion to inches (since we're using dpi) - per measurement sytem
    var measurementProperties = new Object();
    measurementProperties.english = {
        units: ['miles', 'feet', 'inches'],
        abbr: ['mi', 'ft', 'in'],
        inches: [63360, 12, 1]
    };
    measurementProperties.metric = {
        units: ['kilometers', 'meters', 'centimeters'],
        abbr: ['km', 'm', 'cm'],
        inches: [39370.07874, 39.370079, 0.393701]
    };
    // check each measurement unit in the display system
    var comparisonArray = new Array();
    for(var unitIndex = 0; unitIndex < measurementProperties[this.displaySystem].units.length; ++unitIndex) {
        comparisonArray[unitIndex] = new Object();
        var pixelsPerDisplayUnit = this.resolution * measurementProperties[this.displaySystem].inches[unitIndex] / this.scaleDenominator;
        var minSDDisplayLength = (this.minWidth / pixelsPerDisplayUnit) / (this.divisions * this.subdivisions);
        var maxSDDisplayLength = (this.maxWidth / pixelsPerDisplayUnit) / (this.divisions * this.subdivisions);
        // add up scores for each marker (even if numbers aren't displayed)
        for(var valueIndex = 0; valueIndex < (this.divisions * this.subdivisions); ++valueIndex) {
            var minNumber = minSDDisplayLength * (valueIndex + 1);
            var maxNumber = maxSDDisplayLength * (valueIndex + 1);
            var niceNumber = new HandsomeNumber(minNumber, maxNumber);
            comparisonArray[unitIndex][valueIndex] = {value: (niceNumber.value / (valueIndex + 1)), score: 0, tieBreaker: 0, numDec: 0, displayed: 0};
            // now tally up scores for all values given this subdivision length
            for(var valueIndex2 = 0; valueIndex2 < (this.divisions * this.subdivisions); ++valueIndex2) {
                displayedValuePosition = niceNumber.value * (valueIndex2 + 1) / (valueIndex + 1);
                niceNumber2 = new HandsomeNumber(displayedValuePosition, displayedValuePosition);
                var isMajorMeasurement = ((valueIndex2 + 1) % this.subdivisions == 0);
                var isLastMeasurement = ((valueIndex2 + 1) == (this.divisions * this.subdivisions));
                if((this.singleLine && isLastMeasurement) || (!this.singleLine && (isMajorMeasurement || this.showMinorMeasures))) {
                    // count scores for displayed marker measurements
                    comparisonArray[unitIndex][valueIndex].score += niceNumber2.score;
                    comparisonArray[unitIndex][valueIndex].tieBreaker += niceNumber2.tieBreaker;
                    comparisonArray[unitIndex][valueIndex].numDec = Math.max(comparisonArray[unitIndex][valueIndex].numDec, niceNumber2.numDec);
                    comparisonArray[unitIndex][valueIndex].displayed += 1;
                }
                else {
                    // count scores for non-displayed marker measurements
                    comparisonArray[unitIndex][valueIndex].score += niceNumber2.score / this.subdivisions;
                    comparisonArray[unitIndex][valueIndex].tieBreaker += niceNumber2.tieBreaker / this.subdivisions;
                }
            }
            // adjust scores so numbers closer to 1 are preferred for display
            var scoreAdjustment = (unitIndex + 1) * comparisonArray[unitIndex][valueIndex].tieBreaker / comparisonArray[unitIndex][valueIndex].displayed;
            comparisonArray[unitIndex][valueIndex].score *= scoreAdjustment;
        }
    }
    // get the value (subdivision length) with the lowest cumulative score
    var subdivisionDisplayLength = null;
    var displayUnits = null;
    var displayUnitsAbbr = null;
    var subdivisionPixelLength = null;
    var bestScore = Number.POSITIVE_INFINITY;
    var bestTieBreaker = Number.POSITIVE_INFINITY;
    var numDec = 0;
    for(var unitIndex = 0; unitIndex < comparisonArray.length; ++unitIndex) {
        for(valueIndex in comparisonArray[unitIndex]) {
            if((comparisonArray[unitIndex][valueIndex].score < bestScore) || ((comparisonArray[unitIndex][valueIndex].score == bestScore) && (comparisonArray[unitIndex][valueIndex].tieBreaker < bestTieBreaker))) {
                bestScore = comparisonArray[unitIndex][valueIndex].score;
                bestTieBreaker = comparisonArray[unitIndex][valueIndex].tieBreaker;
                subdivisionDisplayLength = comparisonArray[unitIndex][valueIndex].value;
                numDec = comparisonArray[unitIndex][valueIndex].numDec;
                displayUnits = measurementProperties[this.displaySystem].units[unitIndex];
                displayUnitsAbbr = measurementProperties[this.displaySystem].abbr[unitIndex];
                pixelsPerDisplayUnit = this.resolution * measurementProperties[this.displaySystem].inches[unitIndex] / this.scaleDenominator;
                subdivisionPixelLength = pixelsPerDisplayUnit * subdivisionDisplayLength; // round before use in style
            }
        }
    }
    // determine offsets for graphic elements
    var xOffsetMarkerMajor = (styleValue('.sbMarkerMajor', 'borderLeftWidth') + styleValue('.sbMarkerMajor', 'width') + styleValue('.sbMarkerMajor', 'borderRightWidth')) / 2;
    var xOffsetMarkerMinor = (styleValue('.sbMarkerMinor', 'borderLeftWidth') + styleValue('.sbMarkerMinor', 'width') + styleValue('.sbMarkerMinor', 'borderRightWidth')) / 2;
    var xOffsetBar = (styleValue('.sbBar', 'borderLeftWidth') + styleValue('.sbBar', 'borderRightWidth')) / 2;
    var xOffsetBarAlt = (styleValue('.sbBarAlt', 'borderLeftWidth') + styleValue('.sbBarAlt', 'borderRightWidth')) / 2;
    // support for browsers without the Document.styleSheets property (Opera)
    if(!document.styleSheets) {
        // this is a two part hack, one for the offsets here and one for the css below
        xOffsetMarkerMajor = 0.5;
        xOffsetMarkerMinor = 0.5;
    }
    // clean out any old content from containers
    while(this.labelContainer.hasChildNodes()) {
        this.labelContainer.removeChild(this.labelContainer.firstChild);
    }
    while(this.graphicsContainer.hasChildNodes()) {
        this.graphicsContainer.removeChild(this.graphicsContainer.firstChild);
    }
    while(this.numbersContainer.hasChildNodes()) {
        this.numbersContainer.removeChild(this.numbersContainer.firstChild);
    }
    // create all divisions
    var aMarker, aBarPiece, numbersBox, xOffset;
    var alignmentOffset = {
        left: 0,
        center: (-1 * this.divisions * this.subdivisions * subdivisionPixelLength / 2),
        right: (-1 * this.divisions * this.subdivisions * subdivisionPixelLength)
    };
    var xPosition = 0 + alignmentOffset[this.align];
    var markerMeasure = 0;
    for(var divisionIndex = 0; divisionIndex < this.divisions; ++divisionIndex) {
        // set xPosition and markerMeasure to start of division
        xPosition = divisionIndex * this.subdivisions * subdivisionPixelLength;
        xPosition += alignmentOffset[this.align];
        markerMeasure = (divisionIndex == 0) ? 0 : ((divisionIndex * this.subdivisions) * subdivisionDisplayLength).toFixed(numDec);
        // add major marker
        aMarker = document.createElement('div');
        aMarker.className = 'sbMarkerMajor';
        aMarker.style.position = 'absolute';
        aMarker.style.overflow = 'hidden';
        aMarker.style.left = Math.round(xPosition - xOffsetMarkerMajor) + 'px';
        aMarker.appendChild(document.createTextNode(' '));
        this.graphicsContainer.appendChild(aMarker);
        // add initial measure
        if(!this.singleLine) {
            numbersBox = document.createElement('div');
            numbersBox.className = 'sbNumbersBox';
            numbersBox.style.position = 'absolute';
            numbersBox.style.overflow = 'hidden';
            numbersBox.style.textAlign = 'center';
            if(this.showMinorMeasures) {
                numbersBox.style.width = Math.round(subdivisionPixelLength * 2) + 'px';
                numbersBox.style.left = Math.round(xPosition - subdivisionPixelLength) + 'px';
            }
            else {
                numbersBox.style.width = Math.round(this.subdivisions * subdivisionPixelLength * 2) + 'px';
                numbersBox.style.left = Math.round(xPosition - (this.subdivisions * subdivisionPixelLength)) + 'px';
            }
            numbersBox.appendChild(document.createTextNode(markerMeasure));
            this.numbersContainer.appendChild(numbersBox);
        }
        // create all subdivisions
        for(var subdivisionIndex = 0; subdivisionIndex < this.subdivisions; ++subdivisionIndex) {
            aBarPiece = document.createElement('div');
            aBarPiece.style.position = 'absolute';
            aBarPiece.style.overflow = 'hidden';
            aBarPiece.style.width = Math.round(subdivisionPixelLength) + 'px';
            if((subdivisionIndex % 2) == 0) {
                aBarPiece.className = 'sbBar';
                aBarPiece.style.left = Math.round(xPosition - xOffsetBar) + 'px';
            }
            else {
                aBarPiece.className = 'sbBarAlt';
                aBarPiece.style.left = Math.round(xPosition - xOffsetBarAlt) + 'px';
            }
            aBarPiece.appendChild(document.createTextNode(' '));
            this.graphicsContainer.appendChild(aBarPiece);
            // add minor marker if not the last subdivision
            if(subdivisionIndex < (this.subdivisions - 1)) {
                // set xPosition and markerMeasure to end of subdivision
                xPosition = ((divisionIndex * this.subdivisions) + (subdivisionIndex + 1)) * subdivisionPixelLength;
                xPosition += alignmentOffset[this.align];
                markerMeasure = (divisionIndex * this.subdivisions + subdivisionIndex + 1) * subdivisionDisplayLength;
                aMarker = document.createElement('div');
                aMarker.className = 'sbMarkerMinor';
                aMarker.style.position = 'absolute';
                aMarker.style.overflow = 'hidden';
                aMarker.style.left = Math.round(xPosition - xOffsetMarkerMinor) + 'px';
                aMarker.appendChild(document.createTextNode(' '));
                this.graphicsContainer.appendChild(aMarker);
                if(this.showMinorMeasures && !this.singleLine) {
                    // add corresponding measure
                    numbersBox = document.createElement('div');
                    numbersBox.className = 'sbNumbersBox';
                    numbersBox.style.position = 'absolute';
                    numbersBox.style.overflow = 'hidden';
                    numbersBox.style.textAlign = 'center';
                    numbersBox.style.width = Math.round(subdivisionPixelLength * 2) + 'px';
                    numbersBox.style.left = Math.round(xPosition - subdivisionPixelLength) + 'px';
                    numbersBox.appendChild(document.createTextNode(markerMeasure));
                    this.numbersContainer.appendChild(numbersBox);
                }
            }
        }
    }
    // set xPosition and markerMeasure to end of divisions
    xPosition = (this.divisions * this.subdivisions) * subdivisionPixelLength;
    xPosition += alignmentOffset[this.align];
    markerMeasure = ((this.divisions * this.subdivisions) * subdivisionDisplayLength).toFixed(numDec);
    // add the final major marker
    aMarker = document.createElement('div');
    aMarker.className = 'sbMarkerMajor';
    aMarker.style.position = 'absolute';
    aMarker.style.overflow = 'hidden';
    aMarker.style.left = Math.round(xPosition - xOffsetMarkerMajor) + 'px';
    aMarker.appendChild(document.createTextNode(' '));
    this.graphicsContainer.appendChild(aMarker);
    // add final measure
    if(!this.singleLine) {
        numbersBox = document.createElement('div');
        numbersBox.className = 'sbNumbersBox';
        numbersBox.style.position = 'absolute';
        numbersBox.style.overflow = 'hidden';
        numbersBox.style.textAlign = 'center';
        if(this.showMinorMeasures) {
            numbersBox.style.width = Math.round(subdivisionPixelLength * 2) + 'px';
            numbersBox.style.left = Math.round(xPosition - subdivisionPixelLength) + 'px';
        }
        else {
            numbersBox.style.width = Math.round(this.subdivisions * subdivisionPixelLength * 2) + 'px';
            numbersBox.style.left = Math.round(xPosition - (this.subdivisions * subdivisionPixelLength)) + 'px';
        }
        numbersBox.appendChild(document.createTextNode(markerMeasure));
        this.numbersContainer.appendChild(numbersBox);
    }
    // add content to the label container
    var labelBox = document.createElement('div');
    labelBox.style.position = 'absolute';
    var labelText;
    if(this.singleLine) {
        labelText = markerMeasure;
        labelBox.className = 'sbLabelBoxSingleLine';
        labelBox.style.top = '-0.6em';
        labelBox.style.left = (xPosition + 10) + 'px';
    }
    else {
        labelText = '';
        labelBox.className = 'sbLabelBox';
        //labelBox.style.textAlign = 'center';
        //labelBox.style.width = Math.round(this.divisions * this.subdivisions * subdivisionPixelLength) + 'px';
        labelBox.style.left = Math.round(alignmentOffset[this.align]) - 25 + 'px';
        labelBox.style.width = '20px';
        //labelBox.style.left = '10px';
        labelBox.style.overflow = 'hidden';
    }
    if(this.abbreviateLabel) {
        labelText += ' ' + displayUnitsAbbr;
    }
    else {
        labelText += ' ' + displayUnits;
    }
    labelBox.appendChild(document.createTextNode(labelText));
    this.labelContainer.appendChild(labelBox);
    // support for browsers without the Document.styleSheets property (Opera)
    if(!document.styleSheets) {
        // override custom css with default
        var defaultStyle = document.createElement('style');
        defaultStyle.type = 'text/css';
        var styleText = '.sbBar {top: 0px; background: #666666; height: 1px; border: 0;}';
        styleText += '.sbBarAlt {top: 0px; background: #666666; height: 1px; border: 0;}';
        styleText += '.sbMarkerMajor {height: 7px; width: 1px; background: #666666; border: 0;}';
        styleText += '.sbMarkerMinor {height: 5px; width: 1px; background: #666666; border: 0;}';
        styleText += '.sbLabelBox {top: -16px;}';
        styleText += '.sbNumbersBox {top: 7px;}';
        defaultStyle.appendChild(document.createTextNode(styleText));
        document.getElementsByTagName('head').item(0).appendChild(defaultStyle);
    }
    // append the child containers to the parent container
    this.container.appendChild(this.graphicsContainer);
    this.container.appendChild(this.labelContainer);
    this.container.appendChild(this.numbersContainer);
};
ScaleBar.prototype.place = function(elementId) {
    if(elementId == null) {
        document.body.appendChild(this.container);
    }
    else {
        var anElement = document.getElementById(elementId);
        if(anElement != null) {
            anElement.appendChild(this.container);
        }
    }
    this.update();
};
/*****************************************************************************
 *
 * Purpose: set transparency of groups/layers
 * Author:  Armin Burger
 *
 *****************************************************************************
 *
 * Copyright (c) 2003-2007 Armin Burger
 *
 * This file is part of p.mapper.
 *
 * p.mapper is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * p.mapper is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

$.extend(PM.Plugin,
{
    Transparency:
    {
        transpdlg_slider: null,
        dlgOptions: {width:200, height:100, left:250, top:250, resizeable:false, newsize:true, container:'pmDlgContainer', name:'transparency'},
        
        /**
         * Post the Transparency value to PHP GROUP object
         */
        setGroupTransparency: function(pos) {
            var groupname = $('#transpdlg_groupsel option:selected').val();
            if (typeof(groupname)=='undefined') {
                var groupname = $('#layerSliderCont').attr('name');
                var cmenu = 1;
            }
            if (groupname == '#') return false;
            if (cmenu) $('#layerSliderContTab').remove();
            
            var transparency = Math.round(pos  * 100);
            var url = PM_PLUGIN_LOCATION + '/transparency/x_set-transparency.php?' + SID + '&transparency=' + transparency + '&groupname=' + groupname;
            $.ajax({
                type: "POST",
                url: url,
                dataType: "json",
                success: function(response){
                    PM.groupTransparencies[groupname] = transparency;
                    if (response.reload && (PM.layerAutoRefresh == '1')) {
                        //showloading();
                        PM.Map.reloadMap(false);
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    if (window.console) console.log(errorThrown);
                }
            });
        },

        /**
         * Initialize transparency values of groups and create a transparency object for PMap
         */
        initGroupTransparencies: function() {
            var url = PM_PLUGIN_LOCATION + '/transparency/x_get-transparencies.php?' + SID;
            $.ajax({
                type: "POST",
                url: url,
                dataType: "json",
                success: function(response){
                    PM.groupTransparencies = response.transparencies;
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    if (window.console) console.log(errorThrown);
                }
            });
        },

        /**
         * Set slider to transparency value of group
         */
        setTransprarencySlider: function(pgrp) {
            var groupname = pgrp ? pgrp : $('#transpdlg_groupsel option:selected').val();
            if (groupname == '#') return false;
            this.transpdlg_slider.setPosition(PM.groupTransparencies[groupname]/100);
        },

        /**
         * Open the Transparency dialog
         */
        openTransparencyDlg: function() {
			var url = PM_PLUGIN_LOCATION + '/transparency/transparencydlg.phtml?'+SID;
			PM.Dlg.createDnRDlg(this.dlgOptions, _p('Layer transparency'), url);
        },

        /**
         * Create slider for transparency setting
         */
        createTransparencySlider: function(sliderDiv, w) {
            this.transpdlg_slider = new slider(
                sliderDiv,  // id of DIV where slider is inserted
                8,        //height of track
                w,       //width of track
                '#eeeeee', //colour of track
                1,         //thickness of track border
                '#000000', //colour of track border
                2,         //thickness of runner (in the middle of the track)
                '#666666', //colour of runner
                20,        //height of button
                10,        //width of button
                '#999999', //colour of button
                1,         //thickness of button border (shaded to give 3D effect)
                //'<img src="images/slider_updown.gif" style="display:block; margin:auto;" />', //text of button (if any)
                '', //text of button (if any)
                true,      //direction of travel (true = horizontal, false = vertical)
                false, //the name of the function to execute as the slider moves
                'PM.Plugin.Transparency.setGroupTransparency', //the name of the function to execute when the slider stops
                null          //the functions must have already been defined (or use null for none)
                );
        },

        cmOpenTranspDlg: function(gid) {
            $('#layerSliderContTab').remove();
            var dlgx = ($('#jqContextMenu').ileft() - 60) + 'px';
            var dlgy = ($('#jqContextMenu').itop() + 10) + 'px';
            var groupname = gid.replace(/ligrp_/, '');
            //alert(groupname);
            
            var cont = $('<div id="layerSliderContTab"><table><tr><td style="padding:6px 3px"><img src="images/menus/transparency-b.png"/></td><td><div id="layerSliderCont" name="'+groupname+'"></div></tr></table></div>')
                         .css({display:'inline',backgroundColor:'#fff',border:'1px solid #999', position:'absolute',zIndex:99, left:dlgx, top:dlgy, width:'140px', height:'auto'})
                         .dblclick( function () {$(this).remove() })
                         .appendTo('body')
                         .show();
            $().keydown(function (e) {if (e.which == 27) $('#layerSliderContTab').remove()});
            
            this.createTransparencySlider('layerSliderCont', 100);
            this.setTransprarencySlider(groupname);
        }
    }
});
/******************************************************************************
 *
 * Purpose: common js function for pmapper plugins
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

function openResultwin(winurl) {
    try {
        if (PM.queryResultLayout == 'tree') {
            var winw = 300;
            var winh = 450;
        } else {
            var winw = 500;
            var winh = 200;
        }
    } catch(e) {
        var winw = 500;
        var winh = 200;
    }
    
    var w = window.open(winurl, 'resultwin', 'width=' + winw + ',height=' + winh + ',status=yes,resizable=yes,scrollbars=yes');
    w.focus();
    return w;
}

// typewin can be the id of the element like "frame" (with "#")
function openAjaxQueryIn(typewin, dlgOptions, dlgTitle, url, params) {
	if (typewin == 'window') {
		if (url.indexOf('?') == -1) {
			url += '?';
		} else {
			url += '&';
		}
		url += 'addjsandcss=true';
		if (params) {
			url += '&' + params;
		}
		openResultwin(url);
	} else {
		if (url.indexOf('?') > 0) {
			params += (params ? '&' : '') + url.substr(url.indexOf('?') + 1);
		}
		
		PM.ajaxIndicatorShow(false, false);
		$.ajax({
		    url: url,
		    data: params,
	        type: 'POST',
		    dataType: 'html',
		    success: function(response) {
//				PM.ajaxIndicatorHide();
				var resContainer = '';
				if (typewin == 'dynwin') {
					if (!dlgOptions.width) {
						dlgOptions.width = 450;
					}
					if (!dlgOptions.height) {
						dlgOptions.height = 250;
					}
					if (!dlgOptions.container) {
						dlgOptions.container = 'pmDlgContainer';
					}
					PM.Dlg.createDnRDlg(dlgOptions, dlgTitle, false);
					resContainer = '#' + dlgOptions.container + '_MSG';
				} else {
					if (typewin == 'frame' && $('#infoFrame').length > 0) {
						resContainer = '#infoFrame';
					} else if (typewin[0] == '#' && $(typewin).length > 0) { 
						resContainer = typewin;
					}
				}
				$(resContainer).html(response);
			},
			error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (window.console) console.log(errorThrown);
            },
			complete: function() {
				PM.ajaxIndicatorHide();
			}
		});
	} 
}

/**
 * Convert HEXA color to RGB 
 */
function convertHexToRGB(hexColor){
	var r, g, b;
	if (hexColor == '') {
		r = -1;
		g = -1;
		b = -1;
	} else {
	    r = HexToR(hexColor);
	    g = HexToG(hexColor);
	    b = HexToB(hexColor);
	}
	// Do not change the way to add "," and space because of js compression algorythm...
    var rgb = r.toString() + "," + " " + g.toString() + "," + " " + b.toString();

    return rgb;
}
function HexToR(h) {
	return parseInt((cutHex(h)).substring(0,2),16);
} 
function HexToG(h) {
	return parseInt((cutHex(h)).substring(2,4),16);
} 
function HexToB(h) {
	return parseInt((cutHex(h)).substring(4,6),16);
} 
function cutHex(h) {
	return (h.charAt(0)=="#") ? h.substring(1,7):h;
}  

/**
 * Convert RGB color to HEXA 
 */
function convertRgbToHex(num) {
	var decToHex="";
	var arr = [];
	var numStr = new String();
	numStr = num;

	arr = numStr.split(",");

	for(var i=0;i<3;i++){
		var hexArray = new Array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" );
		var code1 = Math.floor(arr[i] / 16);
		var code2 = arr[i] - code1 * 16;
		decToHex += hexArray[code1];
		decToHex += hexArray[code2];
	}
	return (decToHex);
}	

function generateColor(iClass, nbClass, hexColor1, hexColor2) {
	var r1 = HexToR(hexColor1);
    var g1 = HexToG(hexColor1);
    var b1 = HexToB(hexColor1);
	var r2 = HexToR(hexColor2);
    var g2 = HexToG(hexColor2);
    var b2 = HexToB(hexColor2);
	var nb = (nbClass > 1) ? nbClass - 1 : 1;
	var rOffset = Math.round((r2 - r1)/nb);
	var gOffset = Math.round((g2 - g1)/nb);
	var bOffset = Math.round((b2 - b1)/nb);
	var r = Math.max(Math.min(255, r1 + iClass * rOffset),0);
	var g = Math.max(Math.min(255, g1 + iClass * gOffset),0);
	var b = Math.max(Math.min(255, b1 + iClass * bOffset),0);

	var hexaColor = convertRgbToHex(r + ',' + g + ',' + b);
    
	return hexaColor;
}

/** function used to upper the first letter of a word
 * parameters: word  
 * @return: Word
 */
function upperWord(word) {
    var w = word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
    return w;
}

/**
 * 
 * get PM.Plugin[............] object
 * return null if error
 * 
 * @param strIn string (with "." separator).
 * 
 * For instance : "drawing" will return PM.Plugin.drawing object
 */
function getPMPluginObjFromString(strIn) {
	var retPluginObj = null;
	
	var retPluginObjTmp = PM.Plugin;
	var pluginNameCltArray = strIn.split(".");
	var ok = false;
	$.each(pluginNameCltArray, function(index, value) {
		var objTmp = retPluginObjTmp[value];
		if (typeof(objTmp) != "undefined") {
			retPluginObjTmp = objTmp;
			ok = true;
		} else {
			ok = false;
		}
		return ok;
	});
	if (ok) {
		retPluginObj = retPluginObjTmp;
	}
	
	return retPluginObj;
}
/******************************************************************************
 *
 * Purpose: Common drawing class
 * Author:  Jaouad Bennasser, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2009 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

/**********************************************************************************
  USES THE JAVASCRIPT LIBRARIES JSGRAPHICS FROM WALTER ZORN
  SEE FILE /JAVASCRIPT/WZ_JSGRAPHICS.JS FOR DETAILS OF COPYRIGHT
 **********************************************************************************/
/**
 * 1. init_base() : first function, called in derivated classes, initialize parameters and configuration settings.
 * 2. setType() : fix the type of draw, called when the user click on shape image's in box dialog.
 * 3. drawSymbols() : draw the chosen shape.
 * 4. insertTxt() : when the user end drawing, he can insert annotation on the shape.
 * 5. initObjProperties() : init object properties witch will be send to the server.
 * 6. addObject() : add object to array. 
 * 7. generateJson() : generate json string of the shape.
 * 8. sendLayerToServer() : send data to the server, the layer of the shape will be added to pmapper by the PM.Map.ClientDynamicLayers.xxxLayers() function
 * 9. addObjToTab() : add object to the HTML table.
 */


var drawingBase = {
// members:
	drawTypeObj: null, //shape to be drawn : point, line, polygon ...
	tabObjects: null, //will contain an array of shapes
	drawNbObj: 0, //drawing counter
	polyline: new Polygon(), //instantiates a new array of Point objects (see the constructor in javascript/src/pm.geometry.js for more details)
	
// drawing parameters:
	color: null, //color of the shape
	outLineColor: null,	//outline color of the shape
	fontFamily: "arial", //default font-family, -size and -style (used to insert text annotation)
	fontSize: "15px",
	fontStyle: Font.ITALIC_BOLD,
	default_color: '#FF0000', //default drawing color
	default_outlineColor: '#0000FF', //default outline color
	
// members that could/should be re-written in derivated classes:
	selectColorId: '', //color input element's name
	selectOutlineColorId: '', //outline color input element's name
	tableContentId: '', //HTML table content name
	emptyButtonId: '', // empty button name (used to clear all objects drawn)
	tableId: '', //HTML table header name
	
// functions that could/should be re-written in derivated classes:
	init: null, // --> Has to call "this.init_base();" !!!
	beforeSetType: null, //what to do before fixing the type of draw
	afterSetType: null,
	afterDblClick: null, //what to do after double click event
	afterDrawSymbols: null, //what to do at end drawing
	getLayerDef: null, //return a json string with the layer definition
	initCurrentProperties: null, //initialize an array of object's properties
	sendLayers: null, //Send layers to the server
	updateTab_extend: null, //Update html table after an action like deleting an object, close and re-open box dialog, clear all objects ... 
	getLayersToRemove: null, //Get layers to remove when user want to clear all draw by clicking on "emptyButtonId" 
	afterOpenDlg: null,
	addObjToTab_extend: null, //add an object to the html table

	pluginNameSrv: '', // pluginName for init function
	pluginNameClt: '', // pluginName for init function
	
	helpMsg: '',

	onTopAvoidRecursiveCalls: false,
	customOnTopFunction: null,
	
	//called by init() function in derivated classes : initialize parameters	
	init_base: function() {
		this.tabObjects = [];
		this.color = this.default_color;
		this.outLineColor = this.default_outlineColor;

		// redraw while refreshing map, zoom in, zoom out ...
		PM.Map.bindOnMapRefresh({"pluginNameSrv": this.pluginNameSrv, "pluginNameClt": this.pluginNameClt}, function(e) {
			if (PM.Map.maction == e.data.pluginNameSrv) {
    	    	var pluginObject = getPMPluginObjFromString(e.data.pluginNameClt);
    	    	if (pluginObject) {
    	    		pluginObject.redrawPoly();
    	    	}
			}
		});
	},

	//set the type of draw : point, line, polygon
	setType: function(type) {
		var newType = type;

		this.loadPolys(type);
		if (this.beforeSetType) {
			newType = this.beforeSetType(type);
		}

		this.drawTypeObj = newType ? newType : type;
		this.resetDrawing();
		
		if (this.afterSetType) {
			this.afterSetType();
		}
	},

	onTop: function() {
		if (!this.onTopAvoidRecursiveCalls) {
			this.onTopAvoidRecursiveCalls = true;

			if (this.pluginNameSrv) {
		        // change tool --> execute quit function
	        	if (typeof(PM.Map.mode) != 'undefined' && PM.Map.mode != this.pluginNameSrv) {
		            var fct = PM.Map.mode + '_Quit';
		            if ($.isFunction(PM.Map[fct])) {
		                eval('PM.Map.' + fct + '()');
		            }
	        	}
	        	
				// for ontop event: simulate click button
				PM.setTbTDButton(this.pluginNameSrv);
	
				PM.Map.mode = this.pluginNameSrv;
		        PM.Map.maction = this.pluginNameSrv;
		        PM.Map.tool = this.pluginNameSrv;
		        
		        // define the cursor
		        if (PM.useCustomCursor) {
		            PM.setCursor(false, 'crosshair');
		        }
			}

			$('#helpMessage').html(_p(this.helpMsg)).show();

			if ($.isFunction(this.customOnTopFunction)) {
				this.customOnTopFunction();
			}

			this.redrawPoly();
		}
		this.onTopAvoidRecursiveCalls = false;
	},

	/**
	 * Redraw the segment between polyline's or polygon's last point and mouse click in dotted.
	 * parameters: currX,currY in pixels
	 */
	redrawSegmentTmp: function(currX, currY) {
		if (typeof(this.polyline) != 'undefined' && !this.polyline.isClosed()) {
			//this.color = $('#' + this.selectColorId).val() ? $('#' + this.selectColorId).val() : this.default_color;
			
			var nbPoints = this.polyline.getPointsNumber();
			if (nbPoints > 0) {
				var lastPointGeo = this.polyline.getPoint(nbPoints - 1);
				var lastPointPx = PM.Draw.toPxPoint(lastPointGeo);
				
				var mousePoint = new Point(currX, currY); //current mouse X and Y coordinates.
				jg_tmp.clear();
				jg_tmp.setColor(this.outLineColor != null ? this.outLineColor : this.color);		//Specifies the color of the drawing "pen"
				jg_tmp.setStroke(Stroke.DOTTED);	//constant Stroke.DOTTED -> to draw dotted lines.
				if (this.drawTypeObj == 'polygon') {
					jg_tmp.setStroke(2); //Specifies the thickness of the drawing "pen"
					PM.Draw.drawLineSegment(jg_tmp, new Line(lastPointPx, mousePoint));
					jg_tmp.setStroke(1);
					jg_tmp.setStroke(Stroke.DOTTED);
					var firstPointGeo = this.polyline.getPoint(0); //get polyline first point
					var firstPointPx = PM.Draw.toPxPoint(firstPointGeo); //convert to pixels
					PM.Draw.drawLineSegment(jg_tmp, new Line(firstPointPx, mousePoint));
				} else if (this.drawTypeObj == 'line') {
					PM.Draw.drawLineSegment(jg_tmp, new Line(lastPointPx, mousePoint));
				} else if (this.drawTypeObj == 'circle') {
					//draw a cross at circle center	
					var crossSize = 3;
					jg_tmp.drawLine(lastPointPx.x - crossSize, lastPointPx.y - crossSize, lastPointPx.x + crossSize, lastPointPx.y + crossSize);
					jg_tmp.drawLine(lastPointPx.x - crossSize, lastPointPx.y + crossSize, lastPointPx.x + crossSize, lastPointPx.y - crossSize);
					
					this.drawCircle(jg_tmp, lastPointPx, mousePoint);
					
					// calculate radius, circumference, area while moving
					var lastPointPxGeo = PM.Draw.toGeoPoint(lastPointPx);
					var mousePointGeo = PM.Draw.toGeoPoint(mousePoint);			

					var radius = this.calculateCircleRadius(lastPointPxGeo, mousePointGeo);			
					radius = this.roundMeasures(radius, 4);
					
					var circumference = this.calculateCircleCircumference(radius);
					circumference = this.roundMeasures(circumference, 4);
					
					var area = this.calculateCircleArea(radius);
					area = this.roundMeasures(area, 6);
					
					$('#circleRadius').val(radius);
					$('#circleCircumference').val(circumference);				
					$('#circleArea').val(area);	
					
				} else if (this.drawTypeObj == 'rectangle') {
					var x = Math.min(mousePoint.x, lastPointPx.x);
					var y = Math.min(mousePoint.y, lastPointPx.y);
					var larg = Math.abs(mousePoint.x - lastPointPx.x);
					var lon = Math.abs(mousePoint.y - lastPointPx.y);
					
					jg_tmp.drawRect(x, y, larg, lon);
					jg_tmp.paint();
				}	
			}
		}
	},
	
	/**
	 * Main function, draws symbol points between 2 mouseclicks
	 * parameters:  clickX, clickY: coords in pixels; dblClick: true / false 
	 * @return void
	 */
	drawSymbols: function(clickX, clickY, dblClick) {
//		if ((this.drawTypeObj==null) || (this.drawTypeObj=="undefined") || ($('#' + this.tableId).length == 0) || ($('#' + this.tableId).css('display') == 'none')){
		if ((this.drawTypeObj==null) || (this.drawTypeObj=="undefined")){
			return;
		}
		
		if ((clickX < PM.mapW) && (clickY < PM.mapH)) {   // Don't go outside map
			
			var drawNbObjet = this.tabObjects.length;
			var pointPx = new Point(clickX,clickY); // Create a Point object(px coordinates)
			var pointGeo = PM.Draw.toGeoPoint(pointPx); // Return a Point object with geo coordinates
		
			this.initColors(); // fix user's color, outlineColor choice
			
			if (!dblClick) { // SINGLE CLICK

				switch(this.drawTypeObj) {
				
					case 'annotation':
					case 'point':
						if (this.drawTypeObj == 'point') {
							PM.Draw.drawLineSegment(jg,new Line(pointPx, pointPx));	
						}
						var txt = this.insertTxt(pointPx); // insert annotation
						var properties = this.initObjProperties(txt);
						var data = this.addObject(this.drawTypeObj, '[' + pointGeo.toString(',') + ']', properties);
						// Save point into DB
						this.saveObjectIntoDB(data, this.drawTypeObj);
						this.sendLayerToServer(this.drawTypeObj, data);
						
						this.addObjToTab(drawNbObjet, this.drawTypeObj);
						
						break;
						
					case 'line':
					case 'polygon':	
						var nPoints = this.polyline.getPointsNumber();
						
						// First point for start click
			        	if (nPoints < 1) {
			        		this.polyline.addPoint(pointGeo);
			        	} else {
			        		var lastpointGeoPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
			        		if (!pointGeo.equals(lastpointGeoPoly)) {
			        			this.polyline.addPoint(pointGeo);
				        		// USE wz_jsgraphics.js TO DRAW LINE. lastSegment is of Line type                 
				      			var lastSegment = this.polyline.getLastSide();
				      			var sidesNumber = this.polyline.getSidesNumber();                              		
				      			
				      			var lastPointPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
				      			var penultimatePointPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-2);
				      			
				      			var lastPointPolyPx = PM.Draw.toPxPoint(lastPointPoly);	
				      			var penultimatePointPolyPx = PM.Draw.toPxPoint(penultimatePointPoly);
				      			
				      			var lastSegmentPx = new Line(penultimatePointPolyPx , lastPointPolyPx);
				      			
				      			// check for the overlapping of the new side.
				      			// it will never overlap with the previous side  	    	  
				      			if (this.drawTypeObj == 'polygon') {
					      			if (sidesNumber > 2) {      		    
					      				for (var s = 1 ; s < (sidesNumber-1); s++) {                 
					      					var intersectionPoint = this.polyline.getSide(s).intersection(lastSegment);
					      					if (intersectionPoint != null) {                  
					      						alert(_p('digitize_over'));
					      						this.polyline.delPoint(this.polyline.getPointsNumber()-1);
					      						return;                  
					      					}                
					      				}
					      			}
				      			}
				      			PM.Draw.drawLineSegment(jg,lastSegmentPx);
				      		}
			      		} 
						break;
					
					case 'circle':
					case 'rectangle':
						var nPoints = this.polyline.getPointsNumber();
						// many simple click --> remove the first if nb > 2:
						if (nPoints > 2) {
							// keep the last one
							this.polyline.delPoint(0);
						}
						nPoints = this.polyline.getPointsNumber();

						// First point for start click
			        	if (nPoints < 1) {
			        		this.polyline.addPoint(pointGeo);
			        	} else {
							// detect if we are in the second single click of a double click:
			        		var lastpointGeoPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
							// --> not second single click of a double click
			        		if (!pointGeo.equals(lastpointGeoPoly)) {
			        			this.polyline.addPoint(pointGeo);
			        		}	
			        	}
						break;	
										
					default:
						break;
				}
				
			} else { //DOUBLE CLICK 
				
				switch(this.drawTypeObj) {
				
				case 'line':
				case 'polygon':
								
					var nPoints = this.polyline.getPointsNumber();
					if (nPoints <= 1) {
						this.polyline.delPoint(0);
					}
					
					nPoints = this.polyline.getPointsNumber();
					if (nPoints > 0) {
						if (this.drawTypeObj=='polygon') {
							this.polyline.close(); // Closing the polyline to have a polygon  	 
				  	    	
				            // fix the last side
				            var lastSegment = this.polyline.getLastSide();	   
				  	    	var sidesNumber = this.polyline.getSidesNumber();
				  	    	
				  	    	var lastPointPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
			      			var penultimatePointPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-2);
			      			
			      			var lastPointPolyPx = PM.Draw.toPxPoint(lastPointPoly);	
			      			var penultimatePointPolyPx = PM.Draw.toPxPoint(penultimatePointPoly);
			      			
			      			var lastSegmentPx = new Line(penultimatePointPolyPx , lastPointPolyPx);
			
				  	    	// check for the overlapping of the closing side
				  	    	// it will never overlap with the first and the last side
			      			if (this.drawTypeObj == 'polygon') {
				      			for (var s = 2 ; s < (sidesNumber-1); s++) {                 
					                var intersectionPoint = this.polyline.getSide(s).intersection(lastSegment);
					                if (intersectionPoint != null) {                  
					                    alert(_p('digitize_over'));
					                    this.polyline.delPoint(this.polyline.getPointsNumber()-1);
					                    return false;                  
					                }                
					            }
			      			}
				  	    		    	  	    	            		
				  	    	if (lastSegment != null) {
				  	    		PM.Draw.drawLineSegment(jg,lastSegmentPx); //draw polygon last segment
				  	    	}
						}	
			  	    } else {
						alert(_p('dblclick_error')); // you can't double click to start a new polygon
					}	
		            break;
		        
				case 'circle':
					var nPoints = this.polyline.getPointsNumber();
					if (nPoints <= 1) {
						this.polyline.delPoint(0);
					}
					nPoints = this.polyline.getPointsNumber();
					if (nPoints >= 2) {
						
						var centerPointGeo = this.polyline.getPoint(0);
						var borderPointGeo = this.polyline.getPoint(1);
						
						var centerPointPx = PM.Draw.toPxPoint(centerPointGeo);	
						var borderPointPx = PM.Draw.toPxPoint(borderPointGeo);
						
						jg_tmp.clear();
						// draw circle
						this.drawCircle(jg, centerPointPx, borderPointPx);

						// calculate circle diameter with geo coordinaters for the server
						var radiusGeo = this.calculateCircleRadius(centerPointGeo, borderPointGeo);
						var diameterGeo = 2 * radiusGeo;
						if (typeof(this[this.drawTypeObj]) != 'undefined') {
							this[this.drawTypeObj].draw.defaultThickness = diameterGeo;
						}
						this.polyline.delPoint(1); //keep only the first point witch is the circle center.

					} else {
						alert(_p('dblclick_error'));
					}
					break;
				
				case 'rectangle':	
					var nPoints = this.polyline.getPointsNumber();
					if (nPoints <= 1) {
						this.polyline.delPoint(0);
					}
					nPoints = this.polyline.getPointsNumber();
					if (nPoints >= 2) {
						
						var point1Geo = this.polyline.getPoint(0);
						var point2Geo = this.polyline.getPoint(1);
						
						var point3Geo = new Point(point2Geo.x, point1Geo.y);
						var point4Geo = new Point(point1Geo.x, point2Geo.y);
						
						this.polyline.reset();
						this.polyline.addPoint(point1Geo);
						this.polyline.addPoint(point3Geo);
						this.polyline.addPoint(point2Geo);
						this.polyline.addPoint(point4Geo);
						this.polyline.close();
						
					} else {
						alert(_p('dblclick_error'));
						//return false;
					}
					break;
					
				default : 
					break;	
				}
				if (this.afterDblClick) {
	  	    		this.afterDblClick(drawNbObjet);
				}
				this.polyline.reset(); // remove all points from the polygon      
			}
		}
		if (this.afterDrawSymbols) {
			this.afterDrawSymbols(clickX, clickY, dblClick);
		}
	},
	
	//add the object to the html table
	addObjToTab: function(drawNbObjet, type) {
		if (this.addObjToTab_extend) {
			this.addObjToTab_extend(drawNbObjet, type);
		}
	},
	
	//initialize color, outline color to use for drawing
	initColors: function() {
//		this.color = $('#' + this.selectColorId).val() ? $('#' + this.selectColorId).val() : '#FF0000';
//		this.outLineColor = $('#' + this.selectOutlineColorId).val() ? $('#' + this.selectOutlineColorId).val() : '#00FF00';
		jg.setColor(this.outLineColor != null ? this.outLineColor : this.color); //Specifies the color of the drawing "pen"
		jg.setStroke(2); //Specifies the thickness of the drawing "pen" 
	},
	
	setColor: function() {
		var container = null;
		var color = this.default_color;
		
		container = $('#' + this.selectColorId);
		color = this.default_color;
		if (container.length) {
			color = container.val();
		}
		this.color = color;

		if (this.selectOutlineColorId != '') {
			container = $('#' + this.selectOutlineColorId);
			color = this.default_outlineColor;
			if (container.length) {
				color = container.val();
			}
			this.outLineColor = color;
		}
	},
	
	//insert text annotation on the shape
	insertTxt: function(point) {
		jg.setFont(this.fontFamily,this.fontSize,this.fontStyle); //set font-family, -size and -style values
		
		var insertTxt = prompt(_p('Add comment:'), ''); //user can enter his text
		if (insertTxt == null) {
			insertTxt = '';
		}
		jg.drawString(insertTxt, point.x, point.y); //Writes text to the location specified by X and Y
		jg.paint(); //Must be envoked explicitly to draw the internally-generated graphics into the html page.
		
		return insertTxt;
	},
	
	// show color graphically
	showElemColor: function(elem) {
		$(elem).hide().parent().css('background-color', $(elem).val());
	},
	
	/** 
	 * Send data to the server
	 * @param: type, data 
	 * @return: void
	 */
	sendLayerToServer: function(type, data) {
		if (this.getLayerDef) {
			var testDefPlugin = this.getLayerDef(type);
			
			var drawLayer = '[' + this.createLayersString(testDefPlugin, data) + ']';
			
			//to know if the layer will be added or removed, we search the key word "geometry" in the string str
			//removed layers no have geometry
			var str = drawLayer;
			var subStr = "geometry";
			var position = str.indexOf(subStr);
			
			if (position != -1) 
				PM.Map.ClientDynamicLayers.addOrReplaceLayers(drawLayer); //add dynamic layer to pmapper
			else 
				PM.Map.ClientDynamicLayers.removeLayers(drawLayer); //remove dynamic layer to pmapper

//			PM.Map.reloadMap(true);
		}
	},
	
	/** 
	 * Send polygon to server -> insert into db
	 * @param: type, data 
	 * @return: void
	 */
	saveObjectIntoDB: function(data, type) {
		if (this.getLayerDef) {
			data = JSON.parse(data);
			
			var answer = confirm("Shranim narisan objekt?");
			
			if (answer){
				var feat = data.features;
				var len = feat.length - 1;
				
				var coords = feat[len].geometry.coordinates;
				var name = feat[len].properties.comment;
				var color = feat[len].properties.colorHex;
				var outLine = feat[len].properties.outLineHex;
				
				/**
					Save data by ajax call
				*/
				$.ajax({
					url: "incphp/ajax.php",
					type: 'POST',
		       		data: "action=add&coords=" + coords + "&color=" + color + "&outline=" + outLine + "&name=" + name + "&type=" + type
				});
			}
		}
	},
	
	/**
	*	Generate 2D array from normal array
	*	@param: coordinates 
	*	@return: coordinates as 2D
	*/
	generate2DArray: function(coords) {
		coords = JSON.parse(coords);
		var array = new Array();

		for (var i = 0; i < coords.length - 1; i+=2) {

			var x = coords[i];
			var y = coords[i+1];

			// Save points in 2D array
			array.push(new Array(x, y));
		}
		return array;
	},
	
	
	/**
	*	Init data for object to draw
	*	@param: current object
	*	@return: data as a JSON or false if object already exist
	*/
	initObjectData: function(crnt) {
		var type = (crnt.type == 2) ? 'line' : 'point';
		this.drawTypeObj = type;
		this.color = "#" + crnt.color;

		if (type == 2)  this.outlineColor = "#" + crnt.outline;
		var prop = this.initCurrentProperties(crnt.name);
			
		// set up array of coordinates
		var array = JSON.stringify(crnt.coords);
		array = array.substring(1, array.length-1);
		
		if (type == 'line') {
			array = this.generate2DArray(array);
			array = JSON.stringify(array);
			array = array.substring(1, array.length-1);
		}

		// Add object
		var data = this.addObject(this.drawTypeObj, array, prop);
		data = this.remLastIfDuplicate(this.drawTypeObj);

		return data;
	},
	
	/** 
	 * Load all objects from DB
	 * @return: void
	 */
	loadAllObjects: function() {
		//alert("loading");
		$.ajax({
			url: "incphp/ajax.php",
			type: 'POST',
			context: this,
		    data: "action=get_all",
			success: function(data) {
				var tmp = JSON.parse(data);
				if (tmp.result != 'none') {
					var pnt = line = false;
					var allObjects = new Array();
					
					for (var i = 0; i < tmp.length; i++) {
						var o = tmp[i];
						
						var type = (o.type == 2) ? 'line' : 'point';
						
						if ((type == 'line' && line) || (type == 'point' && pnt)) {
						
							var crnt = (type == 'line') ? line : pnt;
							var data = this.initObjectData(crnt);
							
							if (data != false) {
								allObjects.push(data);

								//this.sendLayerToServer(this.drawTypeObj, data);
								this.addObjToTab(this.tabObjects.length - 1, this.drawTypeObj);
							}
						}
						if (type == 'line') line = o;
						else pnt = o;
					}
					
					this.sendLayerToServer(this.drawTypeObj, allObjects);

					// Show last point and last polygon ... needed for showing layers in ToC
					if (line){
						var data = this.initObjectData(line);
						
						if (data) {
							this.sendLayerToServer('line', data);
							this.addObjToTab(this.tabObjects.length - 1, this.drawTypeObj);
						}
					
						this.sendLayerToServer('line', data);
					}
					
					if (pnt) {
						var data = this.initObjectData(pnt);
						
						if (data) {
							this.sendLayerToServer('point', data);
							this.addObjToTab(this.tabObjects.length - 1, this.drawTypeObj);
						}
					
						this.sendLayerToServer('point', data);
					}
				}
			}
		});
	},
	
	
	/** 
	 * initialize object's properties
	 * @param: txt(text grabbed by user) 
	 * @return: properties(array of properties)
	 */
	initObjProperties: function(txt) {

		var pluginProperties = [];

		if (this.initCurrentProperties) {
			pluginProperties = this.initCurrentProperties(txt);
		}
		
		return pluginProperties;
	},
	
	/** 
	 * Delete a specified object
	 * @param drawNbObjet: index of the object 
	 * @return void
	 */
	deleteObj: function(index) {
		var type = this.tabObjects[index]["type"];
		this.tabObjects.splice(index, 1);
		var data = this.generateJson(type);
		
		if (this.sendLayers) {
			this.sendLayers(type, data);
		}
		this.updateTab();
	},
	
	/** 
	 * Show dislpay focused to a specified object
	 * @param drawNbObjet: index of the object 
	 * @return void
	 */
	showObj: function(index) {
		// Get values of selected object
		var type = this.tabObjects[index]["type"];
		var coords = this.tabObjects[index]["coordinates"];

		if (type == "line") coords = "[" + coords + "]";
		coords = JSON.parse(coords);
		
		var minX = maxX = minY = maxY = false;

		if (type == "line") {
			for (var tmp = 0; tmp < coords.length - 1; tmp++) {

				var p = coords[tmp];

				var x = p[0];
				var y = p[1];

				// get min and max zoom values
				if (!minX || x < minX) minX = x;
				if (!maxX || x > maxX) maxX = x;
				if (!minY || y < minY) minY = y;
				if (!maxY || y > maxY) maxY = y;
			}
		}
		
		else {
			minX = maxX = coords[0];
			minY = maxY = coords[1];
		}

		// Width and height of map on screen
		var width = PM.mapW;
		var height = PM.mapH;
		
		// Set point (p1-min values, p2-max values)
		var p1 = new Point(minX, maxY);
		var p2 = new Point(maxX, minY);

		// Convert points to current scale
		p1 = PM.Draw.toPxPoint(p1);
		p2 = PM.Draw.toPxPoint(p2);

		var a = (p1.y < 0) ? " " : "+";
		var b = (p2.x < 0) ? " " : "+";
		var c = (p2.y < 0) ? " " : "+";
		
		p1.x -= 100;
		p1.y -= 100;
		p2.x += 100;
		p2.y += 100;
		
		// If incorrect data, zoom to full Extent
		if (isNaN(p1.x) ||isNaN(p1.y) || isNaN(p2.x) || isNaN(p2.y)) PM.Map.zoomfullext();
		else {
			var extent = p1.x + a + p1.y + b + p2.x + c + p2.y;
			PM.Map.zoomin(extent);
		}
	},
	
	/** 
	 * Updates the table
	 * @return void
	 */
	updateTab: function() {
		this.clearTab();
		if (this.updateTab_extend) {
			this.updateTab_extend();
		}	
	},
	
	/**
	 * remove HTML table content
	 */
	clearTab: function() {
		$("#" + this.tableContentId + " tr:not(:first)").remove();
	},

	/** 
	 * Redraw polylines and polygons
	 * @return void
	 */
	redrawPoly: function() {
		// remove lines
		jg.clear();
		jg_tmp.clear();
		
		if (typeof(this.polyline) == 'undefined')
			return;
		// redraw all polylines or polygons.
		var tabPointsPoly = this.polyline.getPoints();	
					
		for (var iPoint = 0; iPoint < tabPointsPoly.length - 1; iPoint++) {
					
			var point1Geo =  tabPointsPoly[iPoint];
			var point2Geo =  tabPointsPoly[iPoint +1];
						
			var point1Px = PM.Draw.toPxPoint(point1Geo);
			var point2Px =  PM.Draw.toPxPoint(point2Geo);
				
			PM.Draw.drawLineSegment(jg,new Line(point1Px, point2Px));
		}
	},
	
	
	/**
	 * create the string to be sent to the server by concatenating layer's defintion and Data.
	 */
	createLayersString: function(def, data) {
		var ret = '{"def": ' + def + ', "datatype": "GeoJson", "data": ' + data + '}';
		return ret;
	},
	
	/** 
	 * Add an object in Array
	 * @param: type, coordinates, properties
	 * @return: result of generateJson() function call's.
	 */
	addObject: function(type, coordinates, properties) {
		var obj = [];
		obj = ["type", "properties", "coordinates"];
		obj["type"] = type; 
		obj["coordinates"] = coordinates; 
		obj["properties"] = properties; 
		
		this.tabObjects.push(obj);
		
		return this.generateJson(type);
	},
	
	/** 
	 * Remove last object in array if already exist (compare coordinates)
	 * @param: 
	 * @return: result of generateJson() function call's.
	 */
	remLastIfDuplicate: function(type) {		
		// Set up variable with current featuresCollection
		var data = this.generateJson(type);
		data = JSON.parse(data);
		var len = data.features.length;
		
		// Last added polygon coordinates
		var t_coord = data.features[len-1].geometry.coordinates;
		
		var coords = data.features;
		
		for(var i=0; i<coords.length-1; i++) {
			if (JSON.stringify(coords[i].geometry.coordinates) == JSON.stringify(t_coord)) {
				this.tabObjects.pop();
				return false;
			}
		}
		
		// Return JSON type of data
		return this.generateJson(type);
	},
	
	
	/** 
	 * Generate Json of the object
	 * @param type: object's type (point, line, polygon etc ...)
	 * @return out : Json string.
	 */
	generateJson: function(type) {
		var geojsonstr = '';
		for (var i=0; i < this.tabObjects.length; i++) {
			if (this.tabObjects[i]["type"] == type) {
				geojsonstr += this.objGeoToJson(this.tabObjects[i]) + ',';
			}
		}
		// remove the last comma
		if (geojsonstr.length > 0) {
			geojsonstr = geojsonstr.substring(0, geojsonstr.length -1);
		}
		
		var out = '{"type": "FeatureCollection", "features": [' + geojsonstr + ']}';
		return out;
	},
	
	/** 
	 * Delete all objects of the table
	 * @return void
	 */
	clearObjectsTab: function() {

		var data = '{"type": "FeatureCollection", "features": []}';
		$('#' + this.emptyButtonId).hide();
		
		var drawLayer = this.getLayersToRemove(data);
		PM.Map.ClientDynamicLayers.removeLayers(drawLayer);
		
		this.tabObjects.length = 0;
		this.updateTab();
	},
	
	/**
	 * Delete last point, function called when the user press key "DEL"
	 */
	delLastPoint: function() {
		var nPoints = this.polyline.getPointsNumber();
	    
		if (nPoints > 0) {
	    	this.polyline.delPoint(nPoints - 1);
	    	this.redrawPoly(); //Reload drawing after deleting a point 
		}
	},

	/**
	 * Clear all draw, function called when the user press key "ESC"
	 */
	resetDrawing: function() {
	    // remove lines
		this.polyline.reset();
		jg.clear();    
	    jg_tmp.clear();
	},
	
	
	/** 
	 * Check if the string "data" contains the substring "subStr"
	 * parameters: data
	 * @return: void
	 */
	checkGeometry: function(data) {
		
		var str = data;
		var subStr = "geometry";
		var position = str.indexOf(subStr);
		
		if (position != -1)
			str = data;
		else 
			str = '';
		
		return str;
	},
	
	/** 
	 * Generate Json string of the object drawn, 
	 * doc of Json fomat available at : http://www.json.org/
	 */
	objGeoToJson: function(obj) {
		var returnJsonData ="";
		var type = "";
		var coordinates = "[]";
		var properties = "{}";
		var typeOK = true;
		var coordinatesTmp = obj["coordinates"];

		switch (obj["type"]) {
			case 'line':
				type = "LineString";
				break;
			case 'point':
			case 'circle': 
			case 'annotation':	
				type = "Point";
				coordinatesTmp = obj["coordinates"].substring(1, obj["coordinates"].length - 2);
				break;
			case 'polygon':
			case 'rectangle':
				type = "Polygon";
				coordinatesTmp = '[' + obj["coordinates"] + ']';
				break;	
			default:
				typeOK = false;
				break;
		}
		if (typeOK) {
			coordinates = coordinatesTmp;
			properties = "";
			var propertyTitle;
			var propertyValue;
			var quotes;
			for(var i = 0; i < obj["properties"].length; i++){
				propertyTitle = obj["properties"][i];
				propertyValue = obj["properties"][propertyTitle];
				
				// escape '"' character, "&" --> "%26":
				if (propertyTitle == "comment") {
					var regExp = /"/g;
					propertyValue = propertyValue.replace(regExp, '\\"');
					regExp = /&/g;
					propertyValue = propertyValue.replace(regExp, '%26');
				}

				if (typeof(obj["properties"][propertyTitle]) == 'number'){
					quotes = '';
				} else{
					quotes = '"';
				}
				
				properties += '"' + propertyTitle + '": ' + quotes + propertyValue + quotes + ',';
	        }
			properties = properties.substring(0, properties.length -1);	
		}

		returnJsonData = '{ "type": "Feature",';
		returnJsonData += '"geometry": {';
		returnJsonData += '"type": "' + type + '",';
		
		returnJsonData += '"coordinates": [';
		returnJsonData += coordinates; 
		returnJsonData += ']';
		returnJsonData += '},';
		
		returnJsonData += '"properties": {';
		returnJsonData += properties;
		returnJsonData += '}';  
	    returnJsonData += '}';
			
		return returnJsonData;
	},
	
	/**
	 * function used to draw a circle.
	 * parameters: jg, point1, point2 in pixels.
	 * @return: void
	 */
	drawCircle: function (jg, centerPointPx, borderPointPx) {
		var radius = this.calculateCircleRadius(centerPointPx, borderPointPx);

		var x1 = centerPointPx.x - radius;
		var y1 = centerPointPx.y - radius;
		
		var diameter = radius * 2; 
		jg.drawEllipse(x1, y1, diameter, diameter);
		jg.paint();
	},
	
	calculateCircleRadius: function(centerPoint, borderPoint) {
		var radius = 0;
		
		var circleWidth = Math.abs(borderPoint.x - centerPoint.x);
		var circleHeight = Math.abs(borderPoint.y - centerPoint.y);

		radius = Math.sqrt((Math.pow(circleWidth, 2)) + (Math.pow(circleHeight, 2)));
		
	    var cntCircleRadius = Math.round(radius).toString().length;
	    numSize = Math.max(0, (4 - cntCircleRadius));
	    circumference = PM.roundN(radius, numSize); 
		
		return radius;
	},
	
	calculateCircleRadius: function(centerPoint, borderPoint) {
		var radius = 0;
		
		var circleWidth = Math.abs(borderPoint.x - centerPoint.x);
		var circleHeight = Math.abs(borderPoint.y - centerPoint.y);

		radius = Math.sqrt((Math.pow(circleWidth, 2)) + (Math.pow(circleHeight, 2)));

		return radius;
	},
	
	calculateCircleCircumference: function(radius) {
		return Math.PI * 2 * radius;
	},
	
	calculateCircleArea: function(radius) {
		return Math.PI * Math.pow(radius, 2);
	},
	
	roundMeasures: function (measure, radix) {
	    var cntMeasure = Math.round(measure).toString().length;
	    var numSize = Math.max(0, (radix - cntMeasure));
	    measure = PM.roundN(measure, numSize); 			

		return measure;
	},
	
	/**
     * Create the circle input elements
     */
	createCircleDimensionsInput: function() {
        var mStr =  '<form id="circleDimensionsForm"><div class="pm-measure-form"><table class="pm-toolframe"><tr>';
        mStr += '<td NOWRAP>' + _p('Circle') + ' :</td>';
        mStr += '<td NOWRAP>' + _p('Radius') + PM.measureUnits.distance + '</td>';
        mStr += '<td><input type=text size=7 id="circleRadius"></td>';
        mStr += '<td NOWRAP>' + _p('Circumference') + PM.measureUnits.distance + '</td>';
        mStr += '<td><input type=text size=7 id="circleCircumference"></td>';
        mStr += '<td NOWRAP>' + _p('Area') + PM.measureUnits.area + '</td>';
        mStr += '<td><input type=text size=7 id="circleArea"></td>';
        mStr += '</tr></table></form>';
        
        $('#mapToolArea').html(mStr).show();
	}
	
};/******************************************************************************
 *
 * Purpose: Drawing points, polylines, polygons 
 * Author:  Jaouad Bennasser, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2009 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

var drawingPlugin = $.extend({}, drawingBase, 
{
	//Dialog options
	dlgOptions: {width:465, height:250, left:50, top:100, resizeable:true, newsize:true, container:'pmDrawingContainer', name:'Drawing'},
	dlgType: 'dynwin',
	default_color: '#1DF51D', //default drawing color
	default_outlineColor: '#FF0000', //default outline color
	//shape draw and label default properties
	point: {draw:{defaultSymbol:'circle', defaultThickness:10}, label:{defaultFont:'FreeSans', defaultTextSize:6}},
	line: {draw:{defaultSymbol:'circle', defaultThickness:3}, label:{defaultFont:'FreeSans', defaultTextSize:6}},
	//polygon: {draw:{defaultSymbol:'square', defaultThickness:10}, label:{defaultFont:'FreeSans', defaultTextSize:10}},
	//circle: {draw:{defaultSymbol:'drawing-circle', defaultThickness:10}, label:{defaultFont:'FreeSans', defaultTextSize:10}},
	//rectangle: {draw:{defaultSymbol:'square', defaultThickness:10}, label:{defaultFont:'FreeSans', defaultTextSize:10}},
	//annotation: {draw:{defaultSymbol:'', defaultThickness:null}, label:{defaultFont:'FreeSans', defaultTextSize:10}},
	
	//layers definition
	layer_def_point: '{"type":"tplMapFile", "tplname": "drawPoint", "layername": "tocke", "category": "Crtanje"}',
	//layer_def_annotation: '{"type":"tplMapFile", "tplname": "drawAnnotation", "layername": "drawingAnnotation", "category": "Crtanje"}',
	layer_def_line: '{"type":"tplMapFile", "tplname": "drawLine", "layername": "linije", "category": "Crtanje"}',
	//layer_def_polygon: '{"type":"tplMapFile", "tplname": "drawPolygon", "layername": "drawingPolygon", "category": "Crtanje"}',
	//layer_def_circle: '{"type":"tplMapFile", "tplname": "drawCircle", "layername": "drawingCircle", "category": "Crtanje"}',
	//layer_def_rectangle: '{"type":"tplMapFile", "tplname": "drawRectangle", "layername": "drawingRectangle", "category": "Crtanje"}',
	
	pointButtonId: "tb_drawPoint", //point button name
	lineButtonId: "tb_drawLine", //line button name
	//polygonButtonId: "tb_drawPolygon", //polygon button name
	//circleButtonId : "tb_drawCircle", //circle button name	
	//rectangleButtonId: "tb_drawRectangle", //rectangle button name
	//annotationButtonId: "tb_drawAnnotation", //annotation button name
	
	current_properties: [], //array of shape properties

	pluginNameSrv: 'drawing', // pluginName for init function
	pluginNameClt: 'Drawing', // pluginName for init function
	
	helpMsg: 'drawing_help',

	init: function() {
		this.init_base(); //init parameters of common drawing class

		this.selectColorId = this.pluginNameSrv + "color"; //color input element's name for the plugin drawing
		this.selectOutlineColorId = this.pluginNameSrv + "outlineColor"; //outline color input element's name for the plugin drawing
		this.tableContentId = this.pluginNameSrv + "TableContent"; //HTML table content name for the plugin drawing
		this.emptyButtonId = this.pluginNameSrv + "Empty"; //empty button name for the plugin drawing
		this.tableId = this.pluginNameSrv + "Table"; //HTML table header name for the plugin drawing
		
		// load config settings from config_XXXXX.xml file
		if (typeof(PM.ini.pluginsConfig[this.pluginNameSrv]) != 'undefined') {
			var pluginsConfig = PM.ini.pluginsConfig[this.pluginNameSrv];
			if (typeof(pluginsConfig.dlgType) != "undefined") {
				this.dlgType = pluginsConfig.dlgType;
			}
			if (typeof(pluginsConfig.default_color) != "undefined") {
				this.default_color = pluginsConfig.default_color;
				this.color = this.default_color;
			}
			if (typeof(pluginsConfig.default_outlineColor) != "undefined") {
				this.default_outLineColor = pluginsConfig.default_outlineColor;
				this.outLineColor = this.default_outLineColor;
			}
			if (typeof(pluginsConfig.point) != "undefined") {
				this.point = pluginsConfig.point;
			}
			if (typeof(pluginsConfig.line) != "undefined") {
				this.line = pluginsConfig.line;
			}
			if (typeof(pluginsConfig.polygon) != "undefined") {
				this.polygon = pluginsConfig.polygon;
			}
			if (typeof(pluginsConfig.circle) != "undefined") {
				this.circle = pluginsConfig.circle;
			}
			if (typeof(pluginsConfig.rectangle) != "undefined") {
				this.rectangle = pluginsConfig.rectangle;
			}
			if (typeof(pluginsConfig.annotation) != "undefined") {
				this.annotation = pluginsConfig.annotation;
			}
		}
	},
	
	//apply css class to the selected choice in the menu
	beforeSetType: function(type) {
		this.drawTypeObj = type;
		if (!$.isEmptyObject(this.point)) {
			$('#' + this.pointButtonId).removeClass('drawing_point_select').addClass('drawing_point');
		}
		if (!$.isEmptyObject(this.line)) {
			$('#' + this.lineButtonId).removeClass('drawing_line_select').addClass('drawing_line');
		}
		if (!$.isEmptyObject(this.polygon)) {
			$('#' + this.polygonButtonId).removeClass('drawing_polygon_select').addClass('drawing_polygon');
		}
		if (!$.isEmptyObject(this.circle)) {
			$('#' + this.circleButtonId).removeClass('drawing_circle_select').addClass('drawing_circle');
		}
		if (!$.isEmptyObject(this.rectangle)) {
			$('#' + this.rectangleButtonId).removeClass('drawing_rectangle_select').addClass('drawing_rectangle');
		}
		if (!$.isEmptyObject(this.annotation)) {
			$('#' + this.annotationButtonId).removeClass('drawing_annotation_select').addClass('drawing_annotation');
		}

		switch(this.drawTypeObj){
			case 'line':
				if (!$.isEmptyObject(this.line)) {
					$('#' + this.lineButtonId).removeClass('drawing_line').addClass('drawing_line_select');
				}
				break;
			case 'polygon':
				if (!$.isEmptyObject(this.polygon)) {
					$('#' + this.polygonButtonId).removeClass('drawing_polygon').addClass('drawing_polygon_select');
				}
				break;
			case 'point':
				if (!$.isEmptyObject(this.point)) {
					$('#' + this.pointButtonId).removeClass('drawing_point').addClass('drawing_point_select');
				}
				break;
			case 'circle':
				if (!$.isEmptyObject(this.circle)) {
					$('#' + this.circleButtonId).removeClass('drawing_circle').addClass('drawing_circle_select');
				}
				this.createCircleDimensionsInput();
				break;	
			case 'rectangle':
				if (!$.isEmptyObject(this.rectangle)) {
					$('#' + this.rectangleButtonId).removeClass('drawing_rectangle').addClass('drawing_rectangle_select');
				}
				break;		
			case 'annotation':
				if (!$.isEmptyObject(this.annotation)) {
					$('#' + this.annotationButtonId).removeClass('drawing_annotation').addClass('drawing_annotation_select');
				}
				break;		

			default :
				break;
		}
		return this.drawTypeObj;
	},
	
	/**
	 * Create box dialog when the user click on the drawing plugin in toolbar
	 */
	openDlg: function() {
		this.loadPolys(this.drawTypeObj);
		
		$('#helpMessage').html(_p('drawing_help')).show();
		
		if ($('#' + this.tableId).length == 0) {
			// Create dynamic window
			PM.Dlg.createDnRDlg(this.dlgOptions, _p('Drawing'), false, PM.Plugin[this.pluginNameClt].onTop);
			
    		// window contents 
    	    //header table
    	    var htmltable = '<table id="' + this.tableId + '" class="drawingTable" border="0" cellspacing="3" cellpadding="0">';

    		if (!$.isEmptyObject(this.point)) {
	    	    htmltable += '<tr><th id="' + this.pointButtonId + '" class="drawing_type drawing_point" alt="' + _p('Point') + '" title="' + _p('Point') + '" onclick="javascript:PM.Plugin.' + this.pluginNameClt + '.setType(\'point\')" ></th>';
    		}
			if (!$.isEmptyObject(this.line)) {
	    	    htmltable += '<th id="' + this.lineButtonId + '" class="drawing_type drawing_line" alt="' + _p('Line') + '" title="' + _p('Line') + '" onclick="javascript:PM.Plugin.' + this.pluginNameClt + '.setType(\'line\')" ></th>';
    		}
			if (!$.isEmptyObject(this.polygon)) {
	    	    htmltable += '<th id="' + this.polygonButtonId + '" class="drawing_type drawing_polygon" alt="' + _p('Polygon') + '" title="' + _p('Polygon') + '" onclick="javascript:PM.Plugin.' + this.pluginNameClt + '.setType(\'polygon\')" ></th>';
    		}
			if (!$.isEmptyObject(this.circle)) {
				htmltable += '<th id="' + this.circleButtonId + '" class="drawing_type drawing_circle" alt="' + _p('Circle') + '" title="' + _p('Circle') + '" onclick="javascript:PM.Plugin.' + this.pluginNameClt + '.setType(\'circle\')" ></th>';
    		}
			if (!$.isEmptyObject(this.rectangle)) {
				htmltable += '<th id="' + this.rectangleButtonId + '" class="drawing_type drawing_rectangle" alt="' + _p('Rectangle') + '" title="' + _p('Rectangle') + '" onclick="javascript:PM.Plugin.' + this.pluginNameClt + '.setType(\'rectangle\')" ></th>';
    		}
			if (!$.isEmptyObject(this.annotation)) {
				htmltable += '<th id="' + this.annotationButtonId + '" class="drawing_type drawing_annotation" alt="' + _p('Annotation') + '" title="' + _p('Annotation') + '" onclick="javascript:PM.Plugin.' + this.pluginNameClt + '.setType(\'annotation\')" ></th>';
    		}
			htmltable += '<th>' + _p('Preuzete boje') + ' : <br /><input type="text" id="' + this.selectColorId + '" name="' + this.selectColorId + '" value="'+ this.color +'" /> ';
    	    htmltable += '<input type="text" id="' + this.selectOutlineColorId + '" name="' + this.selectOutlineColorId + '" value="'+ this.outLineColor +'" />';
			htmltable += '<td id="polys_td"></td><td id="load_poly" style="background-image: url(' + PM_PLUGIN_LOCATION + '/drawing/images/add.png); width:20px; height: 30px;"></td><td id="rem_poly" style="background-image: url(' + PM_PLUGIN_LOCATION + '/drawing/images/rem.png); width:20px; height: 30px;"></td></tr></table>';

    	    //content table
    	    var htmltableContent = '<table id="' + this.tableContentId + '" class="drawingTableContent" border="0" cellspacing="1" cellpadding="0">';
    	    htmltableContent += '<tr><th>' + _p('Index') + '</th><th>' + _p('Tip') + '</th><th>' + _p('Komentar') + '</th><th>' + _p('Boja') + '</th><th>' + _p('Obod') + '</th>';
    	    htmltableContent += '<th>'+ _p('Bri&scaron;i') + '</th>';
    	    htmltableContent += '</tr></table>';
    	    htmltableContent += '<div id="' + this.emptyButtonId + '"><input type="button" value="'+ _p('Empty') + '" onClick="javascript:PM.Plugin.' + this.pluginNameClt + '.clearObjectsTab()"></input></div>';
    	    
    	    $('#' + this.dlgOptions.container + '_MSG').html(htmltable + htmltableContent);
    	    
    	    $('#' + this.selectColorId).SevenColorPicker();
    	    $('#' + this.selectColorId).bind('change', {"pluginNameClt": this.pluginNameClt}, function(e) {
    	    	var pluginObject = getPMPluginObjFromString(e.data.pluginNameClt);
    	    	if (pluginObject) {
    	    		pluginObject.setColor();
    	    	}
    	    });
    	    $('#' + this.selectOutlineColorId).SevenColorPicker();
    	    $('#' + this.selectOutlineColorId).bind('change', {"pluginNameClt": this.pluginNameClt}, function(e) {
    	    	var pluginObject = getPMPluginObjFromString(e.data.pluginNameClt);
    	    	if (pluginObject) {
    	    		pluginObject.setColor();
    	    	}
    	    });
    	    
    	    $('#' + this.emptyButtonId).hide();

    		this.updateTab();
    		
    		if (!this.drawTypeObj) {
    			$('#' + this.tableId + ' .drawing_type:eq(0)').first().click();
    		}
		} else {
			this.redrawPoly();
		}

		$('#' + this.dlgOptions.container).show();

	    this.setType(this.drawTypeObj);
	},
	
	customOnTopFunction: function() {
	    this.setType(this.drawTypeObj);
	},
	
	//function called when the user end drawing
	afterDblClick: function(drawNbObjet) {
		//get the last point of the poly
		var lastPointPolyGeo = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
		var lastPointPolyPx = PM.Draw.toPxPoint(lastPointPolyGeo);
		
		// insert annotation
		var txt = "";
		if (this.drawTypeObj != "circle") {
			txt = this.insertTxt(lastPointPolyPx); 
		}
		var properties = this.initObjProperties(txt);
		var data = this.addObject(this.drawTypeObj, '[' + this.polyline.toString(',', '],[') + ']', properties);
		this.saveObjectIntoDB(data, this.drawTypeObj);
		this.sendLayerToServer(this.drawTypeObj, data);
		
		this.addObjToTab(drawNbObjet, this.drawTypeObj);
	},

	//display empty button
	afterDrawSymbols: function(clickX, clickY, dblClick) {
		if ((clickX < PM.mapW) && (clickY < PM.mapH)) {   // Don't go outside map
			if (this.tabObjects.length > 0) {
				$('#' + this.emptyButtonId).show();
			}
		}
	},
	
	/** Get layer definition
	 * parameters: type (type of object : point,line ...)  
	 * @return: ret (a json string)
	 */
	getLayerDef: function(type) {
		var ret = false;
		
		switch (type) {
		
			case 'annotation':
				ret = this.layer_def_annotation;
				break;
			
			case 'point':
				ret = this.layer_def_point;
				break;
						
			case 'line':
				ret = this.layer_def_line;
				break;
			
			case 'polygon':
				ret = this.layer_def_polygon;
				break;
			
			case 'circle':
				ret = this.layer_def_circle;
				break;	
			
			case 'rectangle':
				ret = this.layer_def_rectangle;
				break;	
				
			default : 
				break;
		}	
		return ret;
	},
	
	
	/** function used to add an object to the HTML table.
	 * parameters: drawNbObjet(object's index), type(object's type), properties(object's properties)  
	 * @return: void
	 */
	addObjToTab_extend: function(drawNbObjet, type) {

		var txt = this.current_properties["comment"];
		var color = this.current_properties["colorHex"];
		var outLineColor = this.current_properties["outLineHex"];
		
		var upperType = upperWord(type); 
		
		var htmlstr = "<tr><td>" + drawNbObjet + "</td><td class='drawing_" + type + "' alt='" + _p(upperType) + "' title='" + _p(upperType) + "'></td><td>"  + txt + "</td><td><input type='text' class='drawColor' value='" + color + "' /></td><td>";
		if (type != "line" && type != "circle" && type != "annotation") {
			htmlstr += "<input type='text' class='drawOutlineColor' value='" + outLineColor + "' />";
		}
		htmlstr += "</td><td><a href='javascript:PM.Plugin." + this.pluginNameClt + ".showObj(" + (drawNbObjet) + ")'><img alt='" + _p('Show') + "' title='" + _p('Show') + "' width='20' height='20' src='" + PM_PLUGIN_LOCATION + "/drawing/images/show.png'/></a><a href='javascript:PM.Plugin." + this.pluginNameClt + ".deleteObj(" + (drawNbObjet) + ")'><img alt='" + _p('Delete') + "' title='" + _p('Delete') + "' width='20' height='20' src='" + PM_PLUGIN_LOCATION + "/drawing/images/delete.jpeg'/></a></td>";
		htmlstr += "</tr>";
		$("#" + this.tableContentId).append(htmlstr);
/*
		$("#" + this.tableContentId + " tr:not(:first):eq(" + drawNbObjet + ") >> .drawColor").SevenColorPicker();
*/
		var thisPlugin = this;
		// be careful: because of js compression bad algorithm, do not use space followed by point in string
		$("#" + this.tableContentId + " tr:not(:first):eq(" + drawNbObjet + ")" + " " + ".drawColor").each(function() {
			thisPlugin.showElemColor(this);
		});
		$("#" + this.tableContentId + " tr:not(:first):eq(" + drawNbObjet + ")" + " " + ".drawOutlineColor").each(function() {
			thisPlugin.showElemColor(this);
		});
		drawNbObjet++;
	},
	
	//initialize array of object's properties
	initCurrentProperties: function(txt) {
		this.current_properties = ["index", "comment", "symbolThickness", "color", "outLineColor", "colorHex", "outLineHex", 
			"textSize", "fontFamily", "symbolShape"];

		this.current_properties["index"] = this.tabObjects.length;
		this.current_properties["comment"] = txt;
		this.current_properties["symbolThickness"] = this[this.drawTypeObj].draw.defaultThickness;
		this.current_properties["color"] = convertHexToRGB(this.color);
		
		this.current_properties["outLineColor"] = convertHexToRGB(this.outLineColor);
		this.current_properties["colorHex"] = this.color;
		this.current_properties["outLineHex"] = this.outLineColor;
		this.current_properties["textSize"] = this[this.drawTypeObj].label.defaultTextSize;
		this.current_properties["fontFamily"] = this[this.drawTypeObj].label.defaultFont;	
		this.current_properties["symbolShape"] = this[this.drawTypeObj].draw.defaultSymbol;
		
		return this.current_properties;
	},
	
	sendLayers: function(type, data) {
		this.sendLayerToServer(type, data);
	},
	
	/**
	 * Layers to remove for the plugin drawing 
	 */
	getLayersToRemove: function(data) {
		
		var drawLayer = '';
		
		var drawLayerAnno = this.createLayersString(this.layer_def_annotation, data);
		var drawLayerPoint = this.createLayersString(this.layer_def_point, data);
		var drawLayerLine = this.createLayersString(this.layer_def_line, data);
		var drawLayerPolygon = this.createLayersString(this.layer_def_polygon, data);
		var drawLayerCircle = this.createLayersString(this.layer_def_circle, data);
		var drawLayerRectangle = this.createLayersString(this.layer_def_rectangle, data);
		
		drawLayer = '[' + drawLayerAnno + ',' + drawLayerPoint + ',' + drawLayerLine + ',' + drawLayerPolygon + ',' + drawLayerCircle + ',' + drawLayerRectangle + ']';		
		return drawLayer;
	},
	
	/** 
	 * Update html table 
	 * after an action like deleting an object, close and re-open box dialog, clear all objects ...
	 */ 
	updateTab_extend: function() {
		
		for (var iObj = 0 ; iObj < this.tabObjects.length ; iObj++) {
			var typeObj = this.tabObjects[iObj]["type"];
			var properties = this.tabObjects[iObj]["properties"];
			this.current_properties = properties;
			this.addObjToTab(iObj, typeObj);
		}
		this.redrawPoly();
		
		$('#' + this.downloadLinkId + ' a').attr('href','#').parent().hide();
		
		if (this.tabObjects.length == 0) {
			$('#' + this.emptyButtonId).hide();
		} else {
			$('#' + this.emptyButtonId).show();
		}
	},
	
	/**
	 * function used to close box dialog
	 * @return: void
	 */
	drawCloseWindow: function() {
		$('#' + this.dlgPropertiesOptions.container).hide();
	},
	
	/**
	 * function used to update current selection for polygons to draw
	 * @return: string in html format
	 */
	loadPolys: function(type) {
		$("#polys_td").empty();
		$.ajax({
			url: "incphp/ajax.php", 
			type: "POST",
			data: "action=get&type=" + type, 
			success: function(data){
				var res = JSON.parse(data);
				var js = '<script type="text/javascript">$("#load_poly").click(function() {var id = $("#polys").val(); PM.Plugin.Drawing.drawObjectFromDB(id);}); $("#rem_poly").unbind("click").bind("click",function(e) {var id = $("#polys").val(); if (!isNaN(id)) { var ans = confirm("Zelite brisati objekt?"); if (ans) { $.ajax({url: "incphp/ajax.php", type: "POST", data: "action=rem&id=" + id, success: function(data) { data = JSON.parse(data); if (data.msg) { alert(data.msg); } else { PM.Plugin.Drawing.removeDeletedObject(data.coords); } PM.Plugin.Drawing.loadPolys(); }}); }}; });</script>';
				$("#polys_td").html(js + res.result);
			}
		});
	},
	
	removeDeletedObject: function(coords) {
		//Loop through tabObjects...if coordinates are equals, delete it
		var len = this.tabObjects.length;
		
		// set up array of coordinates
		coords = JSON.stringify(coords);
		coords = coords.substring(1, coords.length-1);
		coords = JSON.stringify(this.generate2DArray(coords));
		coords = coords.substring(1, coords.length-1);
		
		// Find and remove object from Tab
		for(var i=0; i<len; i++) {
			//console.log(i);
			var str = this.tabObjects[i].coordinates;
			str = str.replace(" ", "");
			console.log(str + "->" + coords);
			if (str == coords) {
				this.deleteObj(i);
				return;
			}
		}
	},

	/**
	 * function used to draw object, saved into DB
	 * @return: JSON object (polygon/point data)
	 */
	drawObjectFromDB: function(id) {
		if (!isNaN(id)) {
			$.ajax({
				url: "incphp/ajax.php",
				type: "POST",
				context: this,
				data: "action=get&type=poly&id=" + id,
				success: function(data){
					// convert data to object
					data = JSON.parse(data);
					var coords = JSON.parse(data.coords);
					var type = JSON.parse(data.type);
					
					var array = new Array();
					var minX = maxX = minY = maxY = false;

					// Convert to 2D array
					for (var tmp = 0; tmp < coords.length - 1; tmp+=2) {
						
						var x = coords[tmp];
						var y = coords[tmp+1];
						
						// get min and max zoom values
						if (!minX || x < minX) minX = x;
						if (!maxX || x > maxX) maxX = x;
						if (!minY || y < minY) minY = y;
						if (!maxY || y > maxY) maxY = y;
						
						// Save points as 2D array
						array.push(new Array(x, y));
					}
					
					// Width and height of map on screen
					var width = PM.mapW;
					var height = PM.mapH;

					// Set point (p1-min values, p2-max values)
					var p1 = new Point(minX, minY);
					var p2 = new Point(maxX, maxY);

					// Convert points to current scale
					p1 = PM.Draw.toPxPoint(p1);
					p2 = PM.Draw.toPxPoint(p2);

					var data = this.initObjectData(data);
					
					if (data != false) {
						// Zoom to full extent if points are not in current view
						if (p1.x < 0 || p1.y < 0 || p2.x > width || p2.y > height) PM.Map.zoomfullext();
					
						this.sendLayerToServer(this.drawTypeObj, data);
						this.addObjToTab(this.tabObjects.length - 1, this.drawTypeObj);

						$(".jqmdClose").click();
						this.openDlg();
					}
				}
			});	
		}		
	}
});

$.extend(PM.Plugin, {Drawing: drawingPlugin});
			
$.extend(PM.Map,
{
    
	/**
     * custom sample script for extending tool functions
     * called from map.js/domouseclick()
     * must be named '*_click()'
     */
	drawing_click: function() {
		PM.Map.mode = 'drawing';
        PM.Map.maction = 'drawing';
        PM.Map.tool = 'drawing';
        
        // define the cursor
        if (PM.useCustomCursor) {
            PM.setCursor(false, 'crosshair');
        }
        PM.Plugin.Drawing.openDlg();
	},
	
	/**
     * SIMPLE CLICK event in main map
     * start drawing point, line, polygon ...
     * called from map.js/zoombox_apply()
     * must be named '*_start(imgxy)'
     */
	drawing_start: function(imgxy) {
		var pixccoords = imgxy.split('+');
	    var pixX = pixccoords[0];
		var pixY = pixccoords[1];
		
		PM.Plugin.Drawing.drawSymbols(pixX, pixY, false);
	},

	/**
     * MOUSE MOVE event
     */
	drawing_mmove: function(e, moveX, moveY) {
		PM.Plugin.Drawing.redrawSegmentTmp(moveX, moveY);
	},
	
	/**
      * DOUBLE CLICK event
      * end drawing
      */
	drawing_mdblclick: function() {
		PM.Plugin.Drawing.drawSymbols(PM.ZoomBox.upX, PM.ZoomBox.upY, true);
	},
	
	/**
	 * Delete last point when the user press key "DEL"
	 */
	drawing_delKeyPress: function() {
		PM.Plugin.Drawing.delLastPoint();
	},
	
	/**
	 * Remove all measure settings (called when users press key "ESC")
	 */
	drawing_EscKeyPress: function() {
		PM.Plugin.Drawing.resetDrawing();
	},
	
	/**
	 * Quit function
	 */
	drawing_Quit: function() {
		this.drawing_EscKeyPress();
	}		     
});/******************************************************************************
 *
 * Purpose: Add / update / remove dynamic layers to pmapper
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2009 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

$.extend(PM.Map,
{
	ClientDynamicLayers:
	{
		addOrReplaceLayers: function(layers) {
			this.sendLayers(layers, 'addOrReplace');
		},
		
		removeLayers: function(layers) {
			this.sendLayers(layers, 'remove');
		},
		
		addOrReplaceAndRemoveOtherLayers: function(layers) {
			this.sendLayers(layers, 'replaceAll');
		},
		
		sendLayers: function(layers, action) {
			if (action == 'addOrReplace' || action == 'remove' || action == 'replaceAll') {
				var url = PM_PLUGIN_LOCATION + '/clientdynamiclayers/x_clientDynamicLayers.php';
				var params = SID + '&layers=' + layers + '&action=' + action;
				
				$.ajax({
					url:url,
					data: params,
					type: "POST",
					dataType: "json",
					success: function(response){
						var layerstring = PM.Toc.getLayers();
						
						var refreshToc = false;
						if (response.addedLayers.length > 0) {
							PM.defGroupList = $.merge(eval('["' + layerstring.replace(/,/g, '", "') + '"]'), response.addedLayers);
							$.each(response.addedLayers, function() {
								PM.grouplist[this] = {};
								PM.grouplist[this].name = this;
							});
							if (typeof(delete PM.groupTransparencies) != 'undefined') {
								delete PM.groupTransparencies;
							}
							refreshToc = true;
						}
						else 
							if (response.removedLayers.length > 0) {
								$.each(response.removedLayers, function() {
									delete PM.grouplist[this];
								});
								if (typeof(delete PM.groupTransparencies) != 'undefined') {
									delete PM.groupTransparencies;
								}
								refreshToc = true;
							}
						if (refreshToc) {
							PM.Toc.init();
						}
						
						// Update list in PHP session with new layerstring
						var oldlayerstring = layerstring;
						
						// remove "old" layers:
						$.each(response.removedLayers, function(){
							var search = '';
							search = new RegExp('^\s*' + this + '\s*$');
							layerstring = layerstring.replace(search, '');
							search = new RegExp('^\s*' + this + '\s*,');
							layerstring = layerstring.replace(search, '');
							search = new RegExp(',\s*' + this + '\s*$');
							layerstring = layerstring.replace(search, '');
							search = new RegExp(',\s*' + this + '\s*,');
							layerstring = layerstring.replace(search, ',');
						});
						
						// add new layers:
						$.each(response.activeLayers, function(){
							var found = false;
							var search = '';
							if (!found) {
								search = new RegExp('^\s*' + this + '\s*$');
								found = search.test(layerstring);
							}
							if (!found) {
								search = new RegExp('^\s*' + this + '\s*,');
								found = search.test(layerstring);
							}
							if (!found) {
								search = new RegExp(',\s*' + this + '\s*$');
								found = search.test(layerstring);
							}
							if (!found) {
								search = new RegExp(',\s*' + this + '\s*,');
								found = search.test(layerstring);
							}
							if (!found) {
								layerstring += ',' + this;
							}
						});
						
						// update selected layers:
						layerstring = '&groups=' + layerstring;
						PM.Map.updateSelLayers(PM_XAJAX_LOCATION + 'x_layer_update.php?' + SID + layerstring);
						
/*            
						// Add dyn default layers to PM.defGroupList array
			 			$.merge(PM.defGroupList, response.activeLayers);
*/
						// refresh map
						if (oldlayerstring != layerstring) {
							$("#loading").showv();
							setTimeout('PM.Map.reloadMap(false);', 2000);
						}
						else {
							PM.Map.reloadMap(false);
						}
//						PM.Map.reloadMap(false);
					},
		            error: function (XMLHttpRequest, textStatus, errorThrown) {
		                if (window.console) console.log(errorThrown);
		            }
				});
			}
		}
	}
});
/* compress js files */
// Modified by Thomas Raffin (SIRAP)
// compress js files
// keep the first line!!

// Modified by Jaouad Bennasser (SIRAP)
// Focus and resizing

/**
*Seven Color Picker 1.1.0
*Author: Seven Yu
*E-mail: dofyyu#gmail.com
**/
jQuery.fn.SevenColorPicker = function()
{
	var _SCP_FLAG          = '_I_AM_SCP';
	var _SCP_NUMS_PRE_LINE = 8;   // ????????
	var _SCP_ITEM_SIZE     = 15;  // ????
	var _SCP_ITEM_OFFSET   = 2;   // ????
	var _SCP_OFFSET        = 3;   // ????
	var _SCP_BORDER_WIDTH  = 1;   // ????
    var _SCP_COLORS        = ['ff8080','ffff80','80ff80','00ff80','80ffff','0080ff','ff80c0','ff80ff',
							  'ff0000','ffff00','80ff00','00ff40','00ffff','0080c0','8080c0','ff00ff',
							  '804040','ff8040','00ff00','008080','004080','8080ff','800040','ff0080',
							  '800000','ff8000','008000','008040','0000ff','0000a0','800080','8000ff',
							  '400000','804000','004000','004040','000080','000040','400040','408080',
							  '000000','808000','808040','808080','408080','c0c0c0','400040','ffffff'];
    if(!jQuery.SCP_Selecter)
    {
        var html = '<div><ul>';
        var result = $('<div id="seven_color_selecter" />');
        for(var c in _SCP_COLORS)
            html += '<li><a href="javascript:void(\'#'+_SCP_COLORS[c]+'\');" ref="#'+_SCP_COLORS[c]+'" style="background-color:#'+_SCP_COLORS[c]+';"></a></li>';
		html += '</ul><form style="margin:0;padding:3px;clear:both;text-align:center;">'+
                'HEX: <input id="_seven_color_code" maxlength="7" size="10" style="font:10px verdana" /> '+
                '<input type="submit" value=" OK " style="font:10px verdana" /></form></div>';
        result.html(html);
		$(document).mouseup(function(){result.hide()}).find('body').append(result);
        var setColor = function(col)
        {
            if(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.test(col))
            {
                col = col.charAt(0) == '#' ? col : '#' + col;
                jQuery.SCP_Active.css('background-color',col);
                jQuery.SCP_Target.val(col).change();
            }
        }
        result.hide().css({'position':'absolute','font':'10px verdana','margin':0,'padding':0})
        .find('div').css({'background-color':'#f2f2f2','border':_SCP_BORDER_WIDTH+'px solid #999','margin':0,'padding':_SCP_OFFSET})
        .width(_SCP_NUMS_PRE_LINE*(_SCP_ITEM_SIZE+_SCP_ITEM_OFFSET*2+_SCP_BORDER_WIDTH*2))
        .find('form').submit(function()
        {
            setColor($(this).children('#_seven_color_code').val());
            jQuery.SCP_Selecter.hide();
            return false;
        }).end()
        .find('ul').css({'margin':0,'padding':0,'list-style':'none'})
        .find('li').css({'margin':0,'padding':0,'float':'left'})
        .find('a').css({'margin':_SCP_ITEM_OFFSET,'padding':0,'display':'block','border':_SCP_BORDER_WIDTH+'px solid #ccc'})
        .width(_SCP_ITEM_SIZE).height(_SCP_ITEM_SIZE)
        .click(function(){$('#_seven_color_code').val($(this).attr('ref')).focus().select();}) //mouseover => click
        .mousedown(function(){setColor($(this).attr('ref'));})
        .mouseover(function(){$(this).css({'border':_SCP_BORDER_WIDTH+'px solid #333'});})
        .mouseout(function(){$(this).css({'border':_SCP_BORDER_WIDTH+'px solid #ccc'});});
        jQuery.SCP_Selecter = result;
        if(jQuery.browser.msie && jQuery.browser.version == '6.0')
            result.find('div').before('<iframe frameborder="0" width="'+result.width()+'" height="'+result.height()+'" style="position:absolute;z-index:-1;"></iframe>');
    }
    return this.each(function()
    {
		var myPicker = $(this).next(':text');
		if(myPicker.attr('ref') != _SCP_FLAG)
		{
			$(this).hide().after(
                $('<input ref="'+_SCP_FLAG+'" />')
                .width(_SCP_ITEM_SIZE).height(_SCP_ITEM_SIZE)
                .click(function() //mouseover => click
                {
                    var offset = $(this).offset();
                    var left = offset.left;
                    var top  = offset.top+$(this).height()+_SCP_BORDER_WIDTH;
                    jQuery.SCP_Target = $(this).prev();
                    jQuery.SCP_Active = $(this);
// Modified by Jaouad Bennasser (SIRAP)
/*                    
                    jQuery.SCP_Selecter.show().css({'left':left,'top':top}).find('#_seven_color_code').val(jQuery.SCP_Target.val()).focus().select();
*/
                    jQuery.SCP_Selecter.show().css({'left':left,'top':top}).find('#_seven_color_code').val(jQuery.SCP_Target.val()).select();
                }).attr('readonly','true')
                .css({'border':_SCP_BORDER_WIDTH+'px solid #999','cursor':'pointer','padding':0,'background-color':$(this).val()})
            );
		}
    });
}
/******************************************************************************
 *
 * Purpose: common js function for pmapper plugins
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

function openResultwin(winurl) {
    try {
        if (PM.queryResultLayout == 'tree') {
            var winw = 300;
            var winh = 450;
        } else {
            var winw = 500;
            var winh = 200;
        }
    } catch(e) {
        var winw = 500;
        var winh = 200;
    }
    
    var w = window.open(winurl, 'resultwin', 'width=' + winw + ',height=' + winh + ',status=yes,resizable=yes,scrollbars=yes');
    w.focus();
    return w;
}

// typewin can be the id of the element like "frame" (with "#")
function openAjaxQueryIn(typewin, dlgOptions, dlgTitle, url, params) {
	if (typewin == 'window') {
		if (url.indexOf('?') == -1) {
			url += '?';
		} else {
			url += '&';
		}
		url += 'addjsandcss=true';
		if (params) {
			url += '&' + params;
		}
		openResultwin(url);
	} else {
		if (url.indexOf('?') > 0) {
			params += (params ? '&' : '') + url.substr(url.indexOf('?') + 1);
		}
		
		PM.ajaxIndicatorShow(false, false);
		$.ajax({
		    url: url,
		    data: params,
	        type: 'POST',
		    dataType: 'html',
		    success: function(response) {
//				PM.ajaxIndicatorHide();
				var resContainer = '';
				if (typewin == 'dynwin') {
					if (!dlgOptions.width) {
						dlgOptions.width = 450;
					}
					if (!dlgOptions.height) {
						dlgOptions.height = 250;
					}
					if (!dlgOptions.container) {
						dlgOptions.container = 'pmDlgContainer';
					}
					PM.Dlg.createDnRDlg(dlgOptions, dlgTitle, false);
					resContainer = '#' + dlgOptions.container + '_MSG';
				} else {
					if (typewin == 'frame' && $('#infoFrame').length > 0) {
						resContainer = '#infoFrame';
					} else if (typewin[0] == '#' && $(typewin).length > 0) { 
						resContainer = typewin;
					}
				}
				$(resContainer).html(response);
			},
			error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (window.console) console.log(errorThrown);
            },
			complete: function() {
				PM.ajaxIndicatorHide();
			}
		});
	} 
}

/**
 * Convert HEXA color to RGB 
 */
function convertHexToRGB(hexColor){
	var r, g, b;
	if (hexColor == '') {
		r = -1;
		g = -1;
		b = -1;
	} else {
	    r = HexToR(hexColor);
	    g = HexToG(hexColor);
	    b = HexToB(hexColor);
	}
	// Do not change the way to add "," and space because of js compression algorythm...
    var rgb = r.toString() + "," + " " + g.toString() + "," + " " + b.toString();

    return rgb;
}
function HexToR(h) {
	return parseInt((cutHex(h)).substring(0,2),16);
} 
function HexToG(h) {
	return parseInt((cutHex(h)).substring(2,4),16);
} 
function HexToB(h) {
	return parseInt((cutHex(h)).substring(4,6),16);
} 
function cutHex(h) {
	return (h.charAt(0)=="#") ? h.substring(1,7):h;
}  

/**
 * Convert RGB color to HEXA 
 */
function convertRgbToHex(num) {
	var decToHex="";
	var arr = [];
	var numStr = new String();
	numStr = num;

	arr = numStr.split(",");

	for(var i=0;i<3;i++){
		var hexArray = new Array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" );
		var code1 = Math.floor(arr[i] / 16);
		var code2 = arr[i] - code1 * 16;
		decToHex += hexArray[code1];
		decToHex += hexArray[code2];
	}
	return (decToHex);
}	

function generateColor(iClass, nbClass, hexColor1, hexColor2) {
	var r1 = HexToR(hexColor1);
    var g1 = HexToG(hexColor1);
    var b1 = HexToB(hexColor1);
	var r2 = HexToR(hexColor2);
    var g2 = HexToG(hexColor2);
    var b2 = HexToB(hexColor2);
	var nb = (nbClass > 1) ? nbClass - 1 : 1;
	var rOffset = Math.round((r2 - r1)/nb);
	var gOffset = Math.round((g2 - g1)/nb);
	var bOffset = Math.round((b2 - b1)/nb);
	var r = Math.max(Math.min(255, r1 + iClass * rOffset),0);
	var g = Math.max(Math.min(255, g1 + iClass * gOffset),0);
	var b = Math.max(Math.min(255, b1 + iClass * bOffset),0);

	var hexaColor = convertRgbToHex(r + ',' + g + ',' + b);
    
	return hexaColor;
}

/** function used to upper the first letter of a word
 * parameters: word  
 * @return: Word
 */
function upperWord(word) {
    var w = word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
    return w;
}

/**
 * 
 * get PM.Plugin[............] object
 * return null if error
 * 
 * @param strIn string (with "." separator).
 * 
 * For instance : "drawing" will return PM.Plugin.drawing object
 */
function getPMPluginObjFromString(strIn) {
	var retPluginObj = null;
	
	var retPluginObjTmp = PM.Plugin;
	var pluginNameCltArray = strIn.split(".");
	var ok = false;
	$.each(pluginNameCltArray, function(index, value) {
		var objTmp = retPluginObjTmp[value];
		if (typeof(objTmp) != "undefined") {
			retPluginObjTmp = objTmp;
			ok = true;
		} else {
			ok = false;
		}
		return ok;
	});
	if (ok) {
		retPluginObj = retPluginObjTmp;
	}
	
	return retPluginObj;
}
/******************************************************************************
 *
 * Purpose: Common drawing class
 * Author:  Jaouad Bennasser, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2009 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

/**********************************************************************************
  USES THE JAVASCRIPT LIBRARIES JSGRAPHICS FROM WALTER ZORN
  SEE FILE /JAVASCRIPT/WZ_JSGRAPHICS.JS FOR DETAILS OF COPYRIGHT
 **********************************************************************************/
/**
 * 1. init_base() : first function, called in derivated classes, initialize parameters and configuration settings.
 * 2. setType() : fix the type of draw, called when the user click on shape image's in box dialog.
 * 3. drawSymbols() : draw the chosen shape.
 * 4. insertTxt() : when the user end drawing, he can insert annotation on the shape.
 * 5. initObjProperties() : init object properties witch will be send to the server.
 * 6. addObject() : add object to array. 
 * 7. generateJson() : generate json string of the shape.
 * 8. sendLayerToServer() : send data to the server, the layer of the shape will be added to pmapper by the PM.Map.ClientDynamicLayers.xxxLayers() function
 * 9. addObjToTab() : add object to the HTML table.
 */


var drawingBase = {
// members:
	drawTypeObj: null, //shape to be drawn : point, line, polygon ...
	tabObjects: null, //will contain an array of shapes
	drawNbObj: 0, //drawing counter
	polyline: new Polygon(), //instantiates a new array of Point objects (see the constructor in javascript/src/pm.geometry.js for more details)
	
// drawing parameters:
	color: null, //color of the shape
	outLineColor: null,	//outline color of the shape
	fontFamily: "arial", //default font-family, -size and -style (used to insert text annotation)
	fontSize: "15px",
	fontStyle: Font.ITALIC_BOLD,
	default_color: '#FF0000', //default drawing color
	default_outlineColor: '#0000FF', //default outline color
	
// members that could/should be re-written in derivated classes:
	selectColorId: '', //color input element's name
	selectOutlineColorId: '', //outline color input element's name
	tableContentId: '', //HTML table content name
	emptyButtonId: '', // empty button name (used to clear all objects drawn)
	tableId: '', //HTML table header name
	
// functions that could/should be re-written in derivated classes:
	init: null, // --> Has to call "this.init_base();" !!!
	beforeSetType: null, //what to do before fixing the type of draw
	afterSetType: null,
	afterDblClick: null, //what to do after double click event
	afterDrawSymbols: null, //what to do at end drawing
	getLayerDef: null, //return a json string with the layer definition
	initCurrentProperties: null, //initialize an array of object's properties
	sendLayers: null, //Send layers to the server
	updateTab_extend: null, //Update html table after an action like deleting an object, close and re-open box dialog, clear all objects ... 
	getLayersToRemove: null, //Get layers to remove when user want to clear all draw by clicking on "emptyButtonId" 
	afterOpenDlg: null,
	addObjToTab_extend: null, //add an object to the html table

	pluginNameSrv: '', // pluginName for init function
	pluginNameClt: '', // pluginName for init function
	
	helpMsg: '',

	onTopAvoidRecursiveCalls: false,
	customOnTopFunction: null,
	
	//called by init() function in derivated classes : initialize parameters	
	init_base: function() {
		this.tabObjects = [];
		this.color = this.default_color;
		this.outLineColor = this.default_outlineColor;

		// redraw while refreshing map, zoom in, zoom out ...
		PM.Map.bindOnMapRefresh({"pluginNameSrv": this.pluginNameSrv, "pluginNameClt": this.pluginNameClt}, function(e) {
			if (PM.Map.maction == e.data.pluginNameSrv) {
    	    	var pluginObject = getPMPluginObjFromString(e.data.pluginNameClt);
    	    	if (pluginObject) {
    	    		pluginObject.redrawPoly();
    	    	}
			}
		});
	},

	//set the type of draw : point, line, polygon
	setType: function(type) {
		var newType = type;

		this.loadPolys(type);
		if (this.beforeSetType) {
			newType = this.beforeSetType(type);
		}

		this.drawTypeObj = newType ? newType : type;
		this.resetDrawing();
		
		if (this.afterSetType) {
			this.afterSetType();
		}
	},

	onTop: function() {
		if (!this.onTopAvoidRecursiveCalls) {
			this.onTopAvoidRecursiveCalls = true;

			if (this.pluginNameSrv) {
		        // change tool --> execute quit function
	        	if (typeof(PM.Map.mode) != 'undefined' && PM.Map.mode != this.pluginNameSrv) {
		            var fct = PM.Map.mode + '_Quit';
		            if ($.isFunction(PM.Map[fct])) {
		                eval('PM.Map.' + fct + '()');
		            }
	        	}
	        	
				// for ontop event: simulate click button
				PM.setTbTDButton(this.pluginNameSrv);
	
				PM.Map.mode = this.pluginNameSrv;
		        PM.Map.maction = this.pluginNameSrv;
		        PM.Map.tool = this.pluginNameSrv;
		        
		        // define the cursor
		        if (PM.useCustomCursor) {
		            PM.setCursor(false, 'crosshair');
		        }
			}

			$('#helpMessage').html(_p(this.helpMsg)).show();

			if ($.isFunction(this.customOnTopFunction)) {
				this.customOnTopFunction();
			}

			this.redrawPoly();
		}
		this.onTopAvoidRecursiveCalls = false;
	},

	/**
	 * Redraw the segment between polyline's or polygon's last point and mouse click in dotted.
	 * parameters: currX,currY in pixels
	 */
	redrawSegmentTmp: function(currX, currY) {
		if (typeof(this.polyline) != 'undefined' && !this.polyline.isClosed()) {
			//this.color = $('#' + this.selectColorId).val() ? $('#' + this.selectColorId).val() : this.default_color;
			
			var nbPoints = this.polyline.getPointsNumber();
			if (nbPoints > 0) {
				var lastPointGeo = this.polyline.getPoint(nbPoints - 1);
				var lastPointPx = PM.Draw.toPxPoint(lastPointGeo);
				
				var mousePoint = new Point(currX, currY); //current mouse X and Y coordinates.
				jg_tmp.clear();
				jg_tmp.setColor(this.outLineColor != null ? this.outLineColor : this.color);		//Specifies the color of the drawing "pen"
				jg_tmp.setStroke(Stroke.DOTTED);	//constant Stroke.DOTTED -> to draw dotted lines.
				if (this.drawTypeObj == 'polygon') {
					jg_tmp.setStroke(2); //Specifies the thickness of the drawing "pen"
					PM.Draw.drawLineSegment(jg_tmp, new Line(lastPointPx, mousePoint));
					jg_tmp.setStroke(1);
					jg_tmp.setStroke(Stroke.DOTTED);
					var firstPointGeo = this.polyline.getPoint(0); //get polyline first point
					var firstPointPx = PM.Draw.toPxPoint(firstPointGeo); //convert to pixels
					PM.Draw.drawLineSegment(jg_tmp, new Line(firstPointPx, mousePoint));
				} else if (this.drawTypeObj == 'line') {
					PM.Draw.drawLineSegment(jg_tmp, new Line(lastPointPx, mousePoint));
				} else if (this.drawTypeObj == 'circle') {
					//draw a cross at circle center	
					var crossSize = 3;
					jg_tmp.drawLine(lastPointPx.x - crossSize, lastPointPx.y - crossSize, lastPointPx.x + crossSize, lastPointPx.y + crossSize);
					jg_tmp.drawLine(lastPointPx.x - crossSize, lastPointPx.y + crossSize, lastPointPx.x + crossSize, lastPointPx.y - crossSize);
					
					this.drawCircle(jg_tmp, lastPointPx, mousePoint);
					
					// calculate radius, circumference, area while moving
					var lastPointPxGeo = PM.Draw.toGeoPoint(lastPointPx);
					var mousePointGeo = PM.Draw.toGeoPoint(mousePoint);			

					var radius = this.calculateCircleRadius(lastPointPxGeo, mousePointGeo);			
					radius = this.roundMeasures(radius, 4);
					
					var circumference = this.calculateCircleCircumference(radius);
					circumference = this.roundMeasures(circumference, 4);
					
					var area = this.calculateCircleArea(radius);
					area = this.roundMeasures(area, 6);
					
					$('#circleRadius').val(radius);
					$('#circleCircumference').val(circumference);				
					$('#circleArea').val(area);	
					
				} else if (this.drawTypeObj == 'rectangle') {
					var x = Math.min(mousePoint.x, lastPointPx.x);
					var y = Math.min(mousePoint.y, lastPointPx.y);
					var larg = Math.abs(mousePoint.x - lastPointPx.x);
					var lon = Math.abs(mousePoint.y - lastPointPx.y);
					
					jg_tmp.drawRect(x, y, larg, lon);
					jg_tmp.paint();
				}	
			}
		}
	},
	
	/**
	 * Main function, draws symbol points between 2 mouseclicks
	 * parameters:  clickX, clickY: coords in pixels; dblClick: true / false 
	 * @return void
	 */
	drawSymbols: function(clickX, clickY, dblClick) {
//		if ((this.drawTypeObj==null) || (this.drawTypeObj=="undefined") || ($('#' + this.tableId).length == 0) || ($('#' + this.tableId).css('display') == 'none')){
		if ((this.drawTypeObj==null) || (this.drawTypeObj=="undefined")){
			return;
		}
		
		if ((clickX < PM.mapW) && (clickY < PM.mapH)) {   // Don't go outside map
			
			var drawNbObjet = this.tabObjects.length;
			var pointPx = new Point(clickX,clickY); // Create a Point object(px coordinates)
			var pointGeo = PM.Draw.toGeoPoint(pointPx); // Return a Point object with geo coordinates
		
			this.initColors(); // fix user's color, outlineColor choice
			
			if (!dblClick) { // SINGLE CLICK

				switch(this.drawTypeObj) {
				
					case 'annotation':
					case 'point':
						if (this.drawTypeObj == 'point') {
							PM.Draw.drawLineSegment(jg,new Line(pointPx, pointPx));	
						}
						var txt = this.insertTxt(pointPx); // insert annotation
						var properties = this.initObjProperties(txt);
						var data = this.addObject(this.drawTypeObj, '[' + pointGeo.toString(',') + ']', properties);
						// Save point into DB
						this.saveObjectIntoDB(data, this.drawTypeObj);
						this.sendLayerToServer(this.drawTypeObj, data);
						
						this.addObjToTab(drawNbObjet, this.drawTypeObj);
						
						break;
						
					case 'line':
					case 'polygon':	
						var nPoints = this.polyline.getPointsNumber();
						
						// First point for start click
			        	if (nPoints < 1) {
			        		this.polyline.addPoint(pointGeo);
			        	} else {
			        		var lastpointGeoPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
			        		if (!pointGeo.equals(lastpointGeoPoly)) {
			        			this.polyline.addPoint(pointGeo);
				        		// USE wz_jsgraphics.js TO DRAW LINE. lastSegment is of Line type                 
				      			var lastSegment = this.polyline.getLastSide();
				      			var sidesNumber = this.polyline.getSidesNumber();                              		
				      			
				      			var lastPointPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
				      			var penultimatePointPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-2);
				      			
				      			var lastPointPolyPx = PM.Draw.toPxPoint(lastPointPoly);	
				      			var penultimatePointPolyPx = PM.Draw.toPxPoint(penultimatePointPoly);
				      			
				      			var lastSegmentPx = new Line(penultimatePointPolyPx , lastPointPolyPx);
				      			
				      			// check for the overlapping of the new side.
				      			// it will never overlap with the previous side  	    	  
				      			if (this.drawTypeObj == 'polygon') {
					      			if (sidesNumber > 2) {      		    
					      				for (var s = 1 ; s < (sidesNumber-1); s++) {                 
					      					var intersectionPoint = this.polyline.getSide(s).intersection(lastSegment);
					      					if (intersectionPoint != null) {                  
					      						alert(_p('digitize_over'));
					      						this.polyline.delPoint(this.polyline.getPointsNumber()-1);
					      						return;                  
					      					}                
					      				}
					      			}
				      			}
				      			PM.Draw.drawLineSegment(jg,lastSegmentPx);
				      		}
			      		} 
						break;
					
					case 'circle':
					case 'rectangle':
						var nPoints = this.polyline.getPointsNumber();
						// many simple click --> remove the first if nb > 2:
						if (nPoints > 2) {
							// keep the last one
							this.polyline.delPoint(0);
						}
						nPoints = this.polyline.getPointsNumber();

						// First point for start click
			        	if (nPoints < 1) {
			        		this.polyline.addPoint(pointGeo);
			        	} else {
							// detect if we are in the second single click of a double click:
			        		var lastpointGeoPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
							// --> not second single click of a double click
			        		if (!pointGeo.equals(lastpointGeoPoly)) {
			        			this.polyline.addPoint(pointGeo);
			        		}	
			        	}
						break;	
										
					default:
						break;
				}
				
			} else { //DOUBLE CLICK 
				
				switch(this.drawTypeObj) {
				
				case 'line':
				case 'polygon':
								
					var nPoints = this.polyline.getPointsNumber();
					if (nPoints <= 1) {
						this.polyline.delPoint(0);
					}
					
					nPoints = this.polyline.getPointsNumber();
					if (nPoints > 0) {
						if (this.drawTypeObj=='polygon') {
							this.polyline.close(); // Closing the polyline to have a polygon  	 
				  	    	
				            // fix the last side
				            var lastSegment = this.polyline.getLastSide();	   
				  	    	var sidesNumber = this.polyline.getSidesNumber();
				  	    	
				  	    	var lastPointPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-1);
			      			var penultimatePointPoly = this.polyline.getPoint(this.polyline.getPointsNumber()-2);
			      			
			      			var lastPointPolyPx = PM.Draw.toPxPoint(lastPointPoly);	
			      			var penultimatePointPolyPx = PM.Draw.toPxPoint(penultimatePointPoly);
			      			
			      			var lastSegmentPx = new Line(penultimatePointPolyPx , lastPointPolyPx);
			
				  	    	// check for the overlapping of the closing side
				  	    	// it will never overlap with the first and the last side
			      			if (this.drawTypeObj == 'polygon') {
				      			for (var s = 2 ; s < (sidesNumber-1); s++) {                 
					                var intersectionPoint = this.polyline.getSide(s).intersection(lastSegment);
					                if (intersectionPoint != null) {                  
					                    alert(_p('digitize_over'));
					                    this.polyline.delPoint(this.polyline.getPointsNumber()-1);
					                    return false;                  
					                }                
					            }
			      			}
				  	    		    	  	    	            		
				  	    	if (lastSegment != null) {
				  	    		PM.Draw.drawLineSegment(jg,lastSegmentPx); //draw polygon last segment
				  	    	}
						}	
			  	    } else {
						alert(_p('dblclick_error')); // you can't double click to start a new polygon
					}	
		            break;
		        
				case 'circle':
					var nPoints = this.polyline.getPointsNumber();
					if (nPoints <= 1) {
						this.polyline.delPoint(0);
					}
					nPoints = this.polyline.getPointsNumber();
					if (nPoints >= 2) {
						
						var centerPointGeo = this.polyline.getPoint(0);
						var borderPointGeo = this.polyline.getPoint(1);
						
						var centerPointPx = PM.Draw.toPxPoint(centerPointGeo);	
						var borderPointPx = PM.Draw.toPxPoint(borderPointGeo);
						
						jg_tmp.clear();
						// draw circle
						this.drawCircle(jg, centerPointPx, borderPointPx);

						// calculate circle diameter with geo coordinaters for the server
						var radiusGeo = this.calculateCircleRadius(centerPointGeo, borderPointGeo);
						var diameterGeo = 2 * radiusGeo;
						if (typeof(this[this.drawTypeObj]) != 'undefined') {
							this[this.drawTypeObj].draw.defaultThickness = diameterGeo;
						}
						this.polyline.delPoint(1); //keep only the first point witch is the circle center.

					} else {
						alert(_p('dblclick_error'));
					}
					break;
				
				case 'rectangle':	
					var nPoints = this.polyline.getPointsNumber();
					if (nPoints <= 1) {
						this.polyline.delPoint(0);
					}
					nPoints = this.polyline.getPointsNumber();
					if (nPoints >= 2) {
						
						var point1Geo = this.polyline.getPoint(0);
						var point2Geo = this.polyline.getPoint(1);
						
						var point3Geo = new Point(point2Geo.x, point1Geo.y);
						var point4Geo = new Point(point1Geo.x, point2Geo.y);
						
						this.polyline.reset();
						this.polyline.addPoint(point1Geo);
						this.polyline.addPoint(point3Geo);
						this.polyline.addPoint(point2Geo);
						this.polyline.addPoint(point4Geo);
						this.polyline.close();
						
					} else {
						alert(_p('dblclick_error'));
						//return false;
					}
					break;
					
				default : 
					break;	
				}
				if (this.afterDblClick) {
	  	    		this.afterDblClick(drawNbObjet);
				}
				this.polyline.reset(); // remove all points from the polygon      
			}
		}
		if (this.afterDrawSymbols) {
			this.afterDrawSymbols(clickX, clickY, dblClick);
		}
	},
	
	//add the object to the html table
	addObjToTab: function(drawNbObjet, type) {
		if (this.addObjToTab_extend) {
			this.addObjToTab_extend(drawNbObjet, type);
		}
	},
	
	//initialize color, outline color to use for drawing
	initColors: function() {
//		this.color = $('#' + this.selectColorId).val() ? $('#' + this.selectColorId).val() : '#FF0000';
//		this.outLineColor = $('#' + this.selectOutlineColorId).val() ? $('#' + this.selectOutlineColorId).val() : '#00FF00';
		jg.setColor(this.outLineColor != null ? this.outLineColor : this.color); //Specifies the color of the drawing "pen"
		jg.setStroke(2); //Specifies the thickness of the drawing "pen" 
	},
	
	setColor: function() {
		var container = null;
		var color = this.default_color;
		
		container = $('#' + this.selectColorId);
		color = this.default_color;
		if (container.length) {
			color = container.val();
		}
		this.color = color;

		if (this.selectOutlineColorId != '') {
			container = $('#' + this.selectOutlineColorId);
			color = this.default_outlineColor;
			if (container.length) {
				color = container.val();
			}
			this.outLineColor = color;
		}
	},
	
	//insert text annotation on the shape
	insertTxt: function(point) {
		jg.setFont(this.fontFamily,this.fontSize,this.fontStyle); //set font-family, -size and -style values
		
		var insertTxt = prompt(_p('Add comment:'), ''); //user can enter his text
		if (insertTxt == null) {
			insertTxt = '';
		}
		jg.drawString(insertTxt, point.x, point.y); //Writes text to the location specified by X and Y
		jg.paint(); //Must be envoked explicitly to draw the internally-generated graphics into the html page.
		
		return insertTxt;
	},
	
	// show color graphically
	showElemColor: function(elem) {
		$(elem).hide().parent().css('background-color', $(elem).val());
	},
	
	/** 
	 * Send data to the server
	 * @param: type, data 
	 * @return: void
	 */
	sendLayerToServer: function(type, data) {
		if (this.getLayerDef) {
			var testDefPlugin = this.getLayerDef(type);
			
			var drawLayer = '[' + this.createLayersString(testDefPlugin, data) + ']';
			
			//to know if the layer will be added or removed, we search the key word "geometry" in the string str
			//removed layers no have geometry
			var str = drawLayer;
			var subStr = "geometry";
			var position = str.indexOf(subStr);
			
			if (position != -1) 
				PM.Map.ClientDynamicLayers.addOrReplaceLayers(drawLayer); //add dynamic layer to pmapper
			else 
				PM.Map.ClientDynamicLayers.removeLayers(drawLayer); //remove dynamic layer to pmapper

//			PM.Map.reloadMap(true);
		}
	},
	
	/** 
	 * Send polygon to server -> insert into db
	 * @param: type, data 
	 * @return: void
	 */
	saveObjectIntoDB: function(data, type) {
		if (this.getLayerDef) {
			data = JSON.parse(data);
			
			var answer = confirm("Shranim narisan objekt?");
			
			if (answer){
				var feat = data.features;
				var len = feat.length - 1;
				
				var coords = feat[len].geometry.coordinates;
				var name = feat[len].properties.comment;
				var color = feat[len].properties.colorHex;
				var outLine = feat[len].properties.outLineHex;
				
				/**
					Save data by ajax call
				*/
				$.ajax({
					url: "incphp/ajax.php",
					type: 'POST',
		       		data: "action=add&coords=" + coords + "&color=" + color + "&outline=" + outLine + "&name=" + name + "&type=" + type
				});
			}
		}
	},
	
	/**
	*	Generate 2D array from normal array
	*	@param: coordinates 
	*	@return: coordinates as 2D
	*/
	generate2DArray: function(coords) {
		coords = JSON.parse(coords);
		var array = new Array();

		for (var i = 0; i < coords.length - 1; i+=2) {

			var x = coords[i];
			var y = coords[i+1];

			// Save points in 2D array
			array.push(new Array(x, y));
		}
		return array;
	},
	
	
	/**
	*	Init data for object to draw
	*	@param: current object
	*	@return: data as a JSON or false if object already exist
	*/
	initObjectData: function(crnt) {
		var type = (crnt.type == 2) ? 'line' : 'point';
		this.drawTypeObj = type;
		this.color = "#" + crnt.color;

		if (type == 2)  this.outlineColor = "#" + crnt.outline;
		var prop = this.initCurrentProperties(crnt.name);
			
		// set up array of coordinates
		var array = JSON.stringify(crnt.coords);
		array = array.substring(1, array.length-1);
		
		if (type == 'line') {
			array = this.generate2DArray(array);
			array = JSON.stringify(array);
			array = array.substring(1, array.length-1);
		}

		// Add object
		var data = this.addObject(this.drawTypeObj, array, prop);
		data = this.remLastIfDuplicate(this.drawTypeObj);

		return data;
	},
	
	/** 
	 * Load all objects from DB
	 * @return: void
	 */
	loadAllObjects: function() {
		//alert("loading");
		$.ajax({
			url: "incphp/ajax.php",
			type: 'POST',
			context: this,
		    data: "action=get_all",
			success: function(data) {
				var tmp = JSON.parse(data);
				if (tmp.result != 'none') {
					var pnt = line = false;
					var allObjects = new Array();
					
					for (var i = 0; i < tmp.length; i++) {
						var o = tmp[i];
						
						var type = (o.type == 2) ? 'line' : 'point';
						
						if ((type == 'line' && line) || (type == 'point' && pnt)) {
						
							var crnt = (type == 'line') ? line : pnt;
							var data = this.initObjectData(crnt);
							
							if (data != false) {
								allObjects.push(data);

								//this.sendLayerToServer(this.drawTypeObj, data);
								this.addObjToTab(this.tabObjects.length - 1, this.drawTypeObj);
							}
						}
						if (type == 'line') line = o;
						else pnt = o;
					}
					
					this.sendLayerToServer(this.drawTypeObj, allObjects);

					// Show last point and last polygon ... needed for showing layers in ToC
					if (line){
						var data = this.initObjectData(line);
						
						if (data) {
							this.sendLayerToServer('line', data);
							this.addObjToTab(this.tabObjects.length - 1, this.drawTypeObj);
						}
					
						this.sendLayerToServer('line', data);
					}
					
					if (pnt) {
						var data = this.initObjectData(pnt);
						
						if (data) {
							this.sendLayerToServer('point', data);
							this.addObjToTab(this.tabObjects.length - 1, this.drawTypeObj);
						}
					
						this.sendLayerToServer('point', data);
					}
				}
			}
		});
	},
	
	
	/** 
	 * initialize object's properties
	 * @param: txt(text grabbed by user) 
	 * @return: properties(array of properties)
	 */
	initObjProperties: function(txt) {

		var pluginProperties = [];

		if (this.initCurrentProperties) {
			pluginProperties = this.initCurrentProperties(txt);
		}
		
		return pluginProperties;
	},
	
	/** 
	 * Delete a specified object
	 * @param drawNbObjet: index of the object 
	 * @return void
	 */
	deleteObj: function(index) {
		var type = this.tabObjects[index]["type"];
		this.tabObjects.splice(index, 1);
		var data = this.generateJson(type);
		
		if (this.sendLayers) {
			this.sendLayers(type, data);
		}
		this.updateTab();
	},
	
	/** 
	 * Show dislpay focused to a specified object
	 * @param drawNbObjet: index of the object 
	 * @return void
	 */
	showObj: function(index) {
		// Get values of selected object
		var type = this.tabObjects[index]["type"];
		var coords = this.tabObjects[index]["coordinates"];

		if (type == "line") coords = "[" + coords + "]";
		coords = JSON.parse(coords);
		
		var minX = maxX = minY = maxY = false;

		if (type == "line") {
			for (var tmp = 0; tmp < coords.length - 1; tmp++) {

				var p = coords[tmp];

				var x = p[0];
				var y = p[1];

				// get min and max zoom values
				if (!minX || x < minX) minX = x;
				if (!maxX || x > maxX) maxX = x;
				if (!minY || y < minY) minY = y;
				if (!maxY || y > maxY) maxY = y;
			}
		}
		
		else {
			minX = maxX = coords[0];
			minY = maxY = coords[1];
		}

		// Width and height of map on screen
		var width = PM.mapW;
		var height = PM.mapH;
		
		// Set point (p1-min values, p2-max values)
		var p1 = new Point(minX, maxY);
		var p2 = new Point(maxX, minY);

		// Convert points to current scale
		p1 = PM.Draw.toPxPoint(p1);
		p2 = PM.Draw.toPxPoint(p2);

		var a = (p1.y < 0) ? " " : "+";
		var b = (p2.x < 0) ? " " : "+";
		var c = (p2.y < 0) ? " " : "+";
		
		p1.x -= 100;
		p1.y -= 100;
		p2.x += 100;
		p2.y += 100;
		
		// If incorrect data, zoom to full Extent
		if (isNaN(p1.x) ||isNaN(p1.y) || isNaN(p2.x) || isNaN(p2.y)) PM.Map.zoomfullext();
		else {
			var extent = p1.x + a + p1.y + b + p2.x + c + p2.y;
			PM.Map.zoomin(extent);
		}
	},
	
	/** 
	 * Updates the table
	 * @return void
	 */
	updateTab: function() {
		this.clearTab();
		if (this.updateTab_extend) {
			this.updateTab_extend();
		}	
	},
	
	/**
	 * remove HTML table content
	 */
	clearTab: function() {
		$("#" + this.tableContentId + " tr:not(:first)").remove();
	},

	/** 
	 * Redraw polylines and polygons
	 * @return void
	 */
	redrawPoly: function() {
		// remove lines
		jg.clear();
		jg_tmp.clear();
		
		if (typeof(this.polyline) == 'undefined')
			return;
		// redraw all polylines or polygons.
		var tabPointsPoly = this.polyline.getPoints();	
					
		for (var iPoint = 0; iPoint < tabPointsPoly.length - 1; iPoint++) {
					
			var point1Geo =  tabPointsPoly[iPoint];
			var point2Geo =  tabPointsPoly[iPoint +1];
						
			var point1Px = PM.Draw.toPxPoint(point1Geo);
			var point2Px =  PM.Draw.toPxPoint(point2Geo);
				
			PM.Draw.drawLineSegment(jg,new Line(point1Px, point2Px));
		}
	},
	
	
	/**
	 * create the string to be sent to the server by concatenating layer's defintion and Data.
	 */
	createLayersString: function(def, data) {
		var ret = '{"def": ' + def + ', "datatype": "GeoJson", "data": ' + data + '}';
		return ret;
	},
	
	/** 
	 * Add an object in Array
	 * @param: type, coordinates, properties
	 * @return: result of generateJson() function call's.
	 */
	addObject: function(type, coordinates, properties) {
		var obj = [];
		obj = ["type", "properties", "coordinates"];
		obj["type"] = type; 
		obj["coordinates"] = coordinates; 
		obj["properties"] = properties; 
		
		this.tabObjects.push(obj);
		
		return this.generateJson(type);
	},
	
	/** 
	 * Remove last object in array if already exist (compare coordinates)
	 * @param: 
	 * @return: result of generateJson() function call's.
	 */
	remLastIfDuplicate: function(type) {		
		// Set up variable with current featuresCollection
		var data = this.generateJson(type);
		data = JSON.parse(data);
		var len = data.features.length;
		
		// Last added polygon coordinates
		var t_coord = data.features[len-1].geometry.coordinates;
		
		var coords = data.features;
		
		for(var i=0; i<coords.length-1; i++) {
			if (JSON.stringify(coords[i].geometry.coordinates) == JSON.stringify(t_coord)) {
				this.tabObjects.pop();
				return false;
			}
		}
		
		// Return JSON type of data
		return this.generateJson(type);
	},
	
	
	/** 
	 * Generate Json of the object
	 * @param type: object's type (point, line, polygon etc ...)
	 * @return out : Json string.
	 */
	generateJson: function(type) {
		var geojsonstr = '';
		for (var i=0; i < this.tabObjects.length; i++) {
			if (this.tabObjects[i]["type"] == type) {
				geojsonstr += this.objGeoToJson(this.tabObjects[i]) + ',';
			}
		}
		// remove the last comma
		if (geojsonstr.length > 0) {
			geojsonstr = geojsonstr.substring(0, geojsonstr.length -1);
		}
		
		var out = '{"type": "FeatureCollection", "features": [' + geojsonstr + ']}';
		return out;
	},
	
	/** 
	 * Delete all objects of the table
	 * @return void
	 */
	clearObjectsTab: function() {

		var data = '{"type": "FeatureCollection", "features": []}';
		$('#' + this.emptyButtonId).hide();
		
		var drawLayer = this.getLayersToRemove(data);
		PM.Map.ClientDynamicLayers.removeLayers(drawLayer);
		
		this.tabObjects.length = 0;
		this.updateTab();
	},
	
	/**
	 * Delete last point, function called when the user press key "DEL"
	 */
	delLastPoint: function() {
		var nPoints = this.polyline.getPointsNumber();
	    
		if (nPoints > 0) {
	    	this.polyline.delPoint(nPoints - 1);
	    	this.redrawPoly(); //Reload drawing after deleting a point 
		}
	},

	/**
	 * Clear all draw, function called when the user press key "ESC"
	 */
	resetDrawing: function() {
	    // remove lines
		this.polyline.reset();
		jg.clear();    
	    jg_tmp.clear();
	},
	
	
	/** 
	 * Check if the string "data" contains the substring "subStr"
	 * parameters: data
	 * @return: void
	 */
	checkGeometry: function(data) {
		
		var str = data;
		var subStr = "geometry";
		var position = str.indexOf(subStr);
		
		if (position != -1)
			str = data;
		else 
			str = '';
		
		return str;
	},
	
	/** 
	 * Generate Json string of the object drawn, 
	 * doc of Json fomat available at : http://www.json.org/
	 */
	objGeoToJson: function(obj) {
		var returnJsonData ="";
		var type = "";
		var coordinates = "[]";
		var properties = "{}";
		var typeOK = true;
		var coordinatesTmp = obj["coordinates"];

		switch (obj["type"]) {
			case 'line':
				type = "LineString";
				break;
			case 'point':
			case 'circle': 
			case 'annotation':	
				type = "Point";
				coordinatesTmp = obj["coordinates"].substring(1, obj["coordinates"].length - 2);
				break;
			case 'polygon':
			case 'rectangle':
				type = "Polygon";
				coordinatesTmp = '[' + obj["coordinates"] + ']';
				break;	
			default:
				typeOK = false;
				break;
		}
		if (typeOK) {
			coordinates = coordinatesTmp;
			properties = "";
			var propertyTitle;
			var propertyValue;
			var quotes;
			for(var i = 0; i < obj["properties"].length; i++){
				propertyTitle = obj["properties"][i];
				propertyValue = obj["properties"][propertyTitle];
				
				// escape '"' character, "&" --> "%26":
				if (propertyTitle == "comment") {
					var regExp = /"/g;
					propertyValue = propertyValue.replace(regExp, '\\"');
					regExp = /&/g;
					propertyValue = propertyValue.replace(regExp, '%26');
				}

				if (typeof(obj["properties"][propertyTitle]) == 'number'){
					quotes = '';
				} else{
					quotes = '"';
				}
				
				properties += '"' + propertyTitle + '": ' + quotes + propertyValue + quotes + ',';
	        }
			properties = properties.substring(0, properties.length -1);	
		}

		returnJsonData = '{ "type": "Feature",';
		returnJsonData += '"geometry": {';
		returnJsonData += '"type": "' + type + '",';
		
		returnJsonData += '"coordinates": [';
		returnJsonData += coordinates; 
		returnJsonData += ']';
		returnJsonData += '},';
		
		returnJsonData += '"properties": {';
		returnJsonData += properties;
		returnJsonData += '}';  
	    returnJsonData += '}';
			
		return returnJsonData;
	},
	
	/**
	 * function used to draw a circle.
	 * parameters: jg, point1, point2 in pixels.
	 * @return: void
	 */
	drawCircle: function (jg, centerPointPx, borderPointPx) {
		var radius = this.calculateCircleRadius(centerPointPx, borderPointPx);

		var x1 = centerPointPx.x - radius;
		var y1 = centerPointPx.y - radius;
		
		var diameter = radius * 2; 
		jg.drawEllipse(x1, y1, diameter, diameter);
		jg.paint();
	},
	
	calculateCircleRadius: function(centerPoint, borderPoint) {
		var radius = 0;
		
		var circleWidth = Math.abs(borderPoint.x - centerPoint.x);
		var circleHeight = Math.abs(borderPoint.y - centerPoint.y);

		radius = Math.sqrt((Math.pow(circleWidth, 2)) + (Math.pow(circleHeight, 2)));
		
	    var cntCircleRadius = Math.round(radius).toString().length;
	    numSize = Math.max(0, (4 - cntCircleRadius));
	    circumference = PM.roundN(radius, numSize); 
		
		return radius;
	},
	
	calculateCircleRadius: function(centerPoint, borderPoint) {
		var radius = 0;
		
		var circleWidth = Math.abs(borderPoint.x - centerPoint.x);
		var circleHeight = Math.abs(borderPoint.y - centerPoint.y);

		radius = Math.sqrt((Math.pow(circleWidth, 2)) + (Math.pow(circleHeight, 2)));

		return radius;
	},
	
	calculateCircleCircumference: function(radius) {
		return Math.PI * 2 * radius;
	},
	
	calculateCircleArea: function(radius) {
		return Math.PI * Math.pow(radius, 2);
	},
	
	roundMeasures: function (measure, radix) {
	    var cntMeasure = Math.round(measure).toString().length;
	    var numSize = Math.max(0, (radix - cntMeasure));
	    measure = PM.roundN(measure, numSize); 			

		return measure;
	},
	
	/**
     * Create the circle input elements
     */
	createCircleDimensionsInput: function() {
        var mStr =  '<form id="circleDimensionsForm"><div class="pm-measure-form"><table class="pm-toolframe"><tr>';
        mStr += '<td NOWRAP>' + _p('Circle') + ' :</td>';
        mStr += '<td NOWRAP>' + _p('Radius') + PM.measureUnits.distance + '</td>';
        mStr += '<td><input type=text size=7 id="circleRadius"></td>';
        mStr += '<td NOWRAP>' + _p('Circumference') + PM.measureUnits.distance + '</td>';
        mStr += '<td><input type=text size=7 id="circleCircumference"></td>';
        mStr += '<td NOWRAP>' + _p('Area') + PM.measureUnits.area + '</td>';
        mStr += '<td><input type=text size=7 id="circleArea"></td>';
        mStr += '</tr></table></form>';
        
        $('#mapToolArea').html(mStr).show();
	}
	
};/******************************************************************************
 *
 * Purpose: Measure lines lengths and polygons areas
 * Author:  Jaouad Bennasser, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2009 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

var measure2Plugin = $.extend({}, drawingBase, 
{
	//Dialog options
	dlgOptions: {width:320, height:150, left:80, top:125, resizeable:true, newsize:true, container:'pmMeasure2Container', name:'Measure2'},
	dlgType: 'dynwin',
	createMeasureInput: true, //create the measure input elements
	//layers definition
	test_def_distance: '{"type":"tplMapFile", "tplname": "measureDist", "layername": "measureDist", "category": "cat_measure"}',
	test_def_area: '{"type":"tplMapFile", "tplname": "measureArea", "layername": "measureArea", "category": "cat_measure"}',
	
	measureType: null, //type of measure : distance, area
	current_properties: [], //array of measurement properties

	distanceButtonId: "tb_measureDist", //line button name
	areaButtonId: "tb_measureArea", //polygon button name
	
	default_outlineColor: null,

	pluginNameSrv: 'measure2', // pluginName for init function
	pluginNameClt: 'Measure2', // pluginName for init function
	
	init: function() {
		this.init_base(); //init parameters of common drawing class  
		
		this.selectColorId = this.pluginNameSrv + "Color"; //color input element's name for the plugin measure2
		this.tableContentId = this.pluginNameSrv + "TableContent"; //outline color input element's name for the plugin measure2
		this.emptyButtonId = this.pluginNameSrv + "Empty"; //empty button name for the plugin measure2
		this.tableId = this.pluginNameSrv + "Table"; //HTML table header name for the plugin drawing
		
		//load config settings from config_XXXXX.xml file 
		if (typeof(PM.ini.pluginsConfig[this.pluginNameSrv]) != 'undefined') {
			var pluginsConfig = PM.ini.pluginsConfig[this.pluginNameSrv];
			if (typeof(pluginsConfig.dlgType) != 'undefined') {
				this.dlgType = pluginsConfig.dlgType;
			}
			if (typeof(pluginsConfig.default_color) != 'undefined') {
				this.default_color = pluginsConfig.default_color;
				this.color = this.default_color;
			}
			if (typeof(pluginsConfig.createMeasureInput) != 'undefined') {
				this.createMeasureInput = pluginsConfig.createMeasureInput;
			}
		}
	},
	
	//Create box dialog when the user click on the measure2 plugin in toolbar
	openDlg: function() {
		
		if ($('#' + this.tableId).length == 0) {
    		PM.Dlg.createDnRDlg(this.dlgOptions, _p('cat_measure'), false, PM.Plugin[this.pluginNameClt].onTop);
			
    		// window contents 
    		var htmltable = '<table id="' + this.tableId + '" class="drawingTable" border="0" cellspacing="0" cellpadding="0">';
    		//distance and area images, color picker
    		htmltable += '<tr><th id="' + this.distanceButtonId + '" class="measure_type measure_distance" alt="' + _p('Distance') + '" title="' + _p('Distance') + '" onclick="javascript:PM.Plugin.Measure2.setType(\'distance\')" ></th>';
    		htmltable += '<th id="' + this.areaButtonId + '" class="measure_type measure_area" alt="' + _p('Area') + '" title="' + _p('Area') + '" onclick="javascript:PM.Plugin.Measure2.setType(\'area\')" ></th>';
    	    htmltable += '<th>' + _p('Color') + ' : <input type="text" id="' + this.selectColorId + '" name="' + this.selectColorId + '" value="' + this.color + '" /> ';
    	    htmltable += '</tr></table>';
    	    
    	    //table content
    	    var htmltableContent = '<table id="' + this.tableContentId + '" class="drawingTableContent" border="0" cellspacing="1" cellpadding="0">';
    	    htmltableContent += '<tr><th>' + _p('Number') + '</th><th>' + _p('Type') + '</th><th>' + _p('Measure') + '</th><th>' + _p('Color') + '</th><th>' + _p('Delete') + '</th></tr>';
    	    htmltableContent += '</table>';
    			
    	    $('#' + this.dlgOptions.container + '_MSG').html(htmltable + htmltableContent);
    	    $('#' + this.dlgOptions.container + '_MSG').append("<input type='button' id='" + this.emptyButtonId + "' value='" + _p('Empty') + "' onClick='javascript:PM.Plugin.Measure2.clearObjectsTab()'></input>");
    		
    		$('#' + this.selectColorId).SevenColorPicker();
	   	    $('#' + this.selectColorId).bind('change', function() {PM.Plugin.Measure2.setColor()});

    		this.updateTab();

    		if (!this.drawTypeObj) {
    			$('#' + this.tableId + ' .measure_type:eq(0)').first().click();
    		}
		} else {
			this.redrawPoly();
		}

		$('#' + this.dlgOptions.container).show();

		this.setType(this.measureType); //set type of measure : distance, area
	    
	    if (this.createMeasureInput == true || this.createMeasureInput =='true') {
	    	PM.UI.createMeasureInput(); //create the measure input elements
	    }
	},

	
	customOnTopFunction: function() {
		this.setType(this.measureType); //set type of measure : distance, area

	    if (this.createMeasureInput == true || this.createMeasureInput =='true') {
	    	PM.UI.createMeasureInput(); //create the measure input elements
	    }
	},
	
	//apply css class to the selected choice in the menu
	beforeSetType: function(type) {
		this.measureType = type;
		var newTypeObj = this.measureType;
		
		switch(this.measureType) {
			case 'distance': 
				$('#' + this.distanceButtonId).addClass('measure_distance_select');
				$('#' + this.areaButtonId).removeClass('measure_area_select').addClass('measure_area');
				newTypeObj = 'line';
				break;
			case 'area': 
				$('#' + this.areaButtonId).addClass('measure_area_select');
				$('#' + this.distanceButtonId).removeClass('measure_distance_select').addClass('measure_distance');
				newTypeObj = 'polygon';
				break;
			default :
				$('#' + this.areaButtonId).removeClass('measure_area_select').addClass('measure_area');
				$('#' + this.distanceButtonId).removeClass('measure_distance_select').addClass('measure_distance');
				break;
		}
		
		return newTypeObj;
	},
	
	
	/**
	 * Calculate Area or distance when user double click
	 * @param nbMeasure
	 * @return void
	 */
	afterDblClick: function(nbMeasure) {
		var unit;
		var measure;
		var txt;
		
		if (this.drawTypeObj == "line") {
			unit = PM.measureUnits.distance;
			measure = this.calculLengthPoly(this.polyline);
		} else if (this.drawTypeObj == "polygon"){
			unit = PM.measureUnits.area;
			measure = this.calculAreaPoly(this.polyline);
			
			var length = this.calculLengthPoly(this.polyline);
			if (this.polyline.getPointsNumber() == 3) {
				length = length /2;
			}
			var area = this.calculAreaPoly(this.polyline);
			
			// Change input text box to 'Area'
			$('#measureFormSum').val(length);
			$("#mSegTxt").html(_p('Area') + PM.measureUnits.area); 
		    $('#measureFormSeg').val(area);
		}
		
		unit = this.removeHooks(unit);
		txt = measure + ' ' + unit; 
		
		var properties = this.initObjProperties(txt);
		var data = this.addObject(this.drawTypeObj, '[' + this.polyline.toString(',', '],[') + ']', properties);
		
		if (this.drawTypeObj == "line") {
			this.sendLayerToServer('distance', data);
		} else if (this.drawTypeObj == "polygon"){
			this.sendLayerToServer('area', data);
		}
		
		this.addObjToTab(nbMeasure, this.measureType);
		$('#' + this.emptyButtonId).show();
	},
	
	
	/**
	 * Plugin measure2 properties 
	 */
	initCurrentProperties: function(txt) {
		this.current_properties = ["comment", "color", "measureType"];
		this.current_properties["comment"] = txt;
		this.current_properties["color"] = this.color;
		this.current_properties["measureType"] = this.measureType;
		
		return this.current_properties;
	},
	
	/** Used to add a measure to the HTML table.
	 * @param: nbpoly: number of polygon or polyline ; type: line, polygon 
	 * @return: void
	 */
	addObjToTab_extend: function(nbpoly, type) {
		var measure = this.current_properties["comment"];
		var color = this.current_properties["color"];
		var measureType = this.current_properties["measureType"];
		var upperMeasureType = upperWord(measureType);
		$("#" + this.tableContentId).append("<tr><td>" + (nbpoly + 1) + "</td><td class='measure_" + measureType + "' alt='" + _p(upperMeasureType) + "' title='" + _p(upperMeasureType) + "'></td><td>" + measure + "</td><td><input type='text' class='measure2Color' value='" + color + "' /></td><td><a href='javascript:PM.Plugin.Measure2.deleteObj(" + (nbpoly) + ")'><img alt='delete' title='" + _p('Delete') + "' width='20' height='20' src='" + PM_PLUGIN_LOCATION + "/measure2/images/delete.jpeg'/></a></td></tr>");
		var thisPlugin = this;
		// be careful: because of js compression bad algorithm, do not use space followed by point in string
		$("#" + this.tableContentId + " tr:not(:first):eq(" + (nbpoly) + ")" + " " + ".measure2Color").each(function() {
			thisPlugin.showElemColor(this);
		});
	},
	
	
	/** 
	 * Calculate polyline length
	 * @param: polyGEO Polyline object passed to the handler
	 * @return: perimGEO polyline length 
	 */
	calculLengthPoly: function(polyGEO) {
	   
		var perimGEO  = polyGEO.getPerimeter() / PM.measureUnits.factor ;
		var cntPerLen = Math.round(perimGEO).toString().length;
	    var numSize = Math.max(0, (4 - cntPerLen));
	    perimGEO = PM.roundN(perimGEO, numSize); 
	    
		return perimGEO;
	},
	
	/** 
	 * Calculate last segment length's
	 * @param poly: Polygon object passed to the handler
	 * @return: void 
	 */
	calculLastSegLength: function(poly) {
		
		var segLength = poly.getSideLength(poly.getSidesNumber()) / PM.measureUnits.factor ;
	    var cntSegLen = Math.round(segLength).toString().length;
	    numSize = Math.max(0, (4 - cntSegLen));
	    segLength = PM.roundN(segLength, numSize); 
	    $('#measureFormSeg').val(segLength);
	},
	
	
	/** 
	 * Calculate polygon area
	 * @param polyGEO: Polygon object passed to the handler
	 * @return areaGEO: polygon area 
	 */
	calculAreaPoly: function(polyGEO) {
		
		var perimGEO = polyGEO.getPerimeter() / PM.measureUnits.factor;
		var cntPerLen = Math.round(perimGEO).toString().length;
	    numSize = Math.max(0, (4 - cntPerLen));
		
	    var areaGEO = polyGEO.getArea() / (PM.measureUnits.factor * PM.measureUnits.factor);
		areaGEO = PM.roundN(areaGEO, numSize-1);
		areaGEO = Math.abs(areaGEO); // absolute value
		
		return areaGEO;
	},
	
	/** 
	 * remove hooks from units measurement (distance, area)
	 * @param unit: in this format [m]
	 * @return measureUnit: new unit in this format m 
	 */
	removeHooks: function(unit) {

		var measureUnit = unit.split('['); //remove "[ ]"
		measureUnit = measureUnit[1].split(']');
		measureUnit = measureUnit[0];

		return measureUnit; 
	},
	
	/**
	 * measure length between a point and mouse cursor
	 * @param pluginPolyline
	 * @param mousePoint
	 * @return void
	 */
	calculateLengthTmp: function(currX, currY) {
		if (typeof(PM.Plugin.Measure2.polyline) != 'undefined') {
			$('#mapToolArea').show();
			
			if (this.polyline.getPointsNumber() > 0) {
				var mousePoint = new Point(currX,currY);
				var mousePointGeo = PM.Draw.toGeoPoint(mousePoint);
				this.polyline.addPoint(mousePointGeo);
				var lTmp = this.calculLengthPoly(this.polyline);
				$('#measureFormSum').val(lTmp);
				
				this.calculLastSegLength(this.polyline); // last segment length
				this.polyline.delPoint(this.polyline.getPointsNumber()-1);
			}
		}
	},
	
	/** Get layer definition
	 * parameters: type (type of measure: distance, area)  
	 * @return: ret (a json string)
	 */
	getLayerDef: function(type) {
		var ret = false;
		
		switch (type) {
			case 'distance':
				ret = this.test_def_distance;
				break;
			case 'area':
				ret = this.test_def_area;
				break;
			default: 
				break;
		}	
		return ret;
	},
	
	sendLayers: function(type, data) {
		if (type == 'line') {
			this.sendLayerToServer('distance', data);
		} else if (type == 'polygon'){
			this.sendLayerToServer('area', data);
		}
	},
	
	/**
	 * Function called by clearObjectsTab() in drawing.js to get layers to remove 
	 */
	getLayersToRemove: function(data) {
		var drawLayer = '';
		var drawLayerMeasureDist = this.createLayersString(this.test_def_distance, data);
		var drawLayerMeasureArea = this.createLayersString(this.test_def_area, data);
		
		drawLayer = '[' + drawLayerMeasureDist + ',' + drawLayerMeasureArea + ']';
		return drawLayer;
	},
	
	/**
	 * Updates html table 
	 */
	updateTab_extend: function() {
		for (var iPoly = 0 ; iPoly < this.tabObjects.length ; iPoly++) {
			var type = this.tabObjects[iPoly]["type"];
			var properties = this.tabObjects[iPoly]["properties"];
			this.current_properties = properties;
			this.addObjToTab(iPoly, type);
			
		}
		this.redrawPoly();
		
		if (this.tabObjects.length == 0) {
			$('#' + this.emptyButtonId).hide();
		} else {
			$('#' + this.emptyButtonId).show();
		}
	},
	
	/**
	 * Reset form fields
	 */
	reloadData: function() {
	    if (this.polyline.getSidesNumber() == 0) {
	        // Reset form fields 
	        if ($('#measureForm').length > 0) {
	            $('#measureFormSum').val('');
	            $('#measureFormSeg').val('');
	        	$("#mSegTxt").html(_p('Segment') + PM.measureUnits.distance); 
	        }  
	    }
	}
	
});

$.extend(PM.Plugin, {Measure2: measure2Plugin});	    	


$.extend(PM.Map,
{
	/**
	* called from map.js/domouseclick()
	*/
	measure2_click: function() {
		PM.Map.mode = 'measure2';
		PM.Map.maction = 'measure2';
		PM.Map.tool = 'measure2';
		
		// define the cursor
		if (PM.useCustomCursor) {
			PM.setCursor(false, 'crosshair');
		}
		PM.Plugin.Measure2.openDlg();
	},

	/**
	 * SIMPLE CLICK event in main map
	 * start drawing polyline
	 * called from map.js/zoombox_apply()
	 */
	measure2_start: function(imgxy) {
		var pixccoords = imgxy.split('+');
		var pixX = pixccoords[0];
		var pixY = pixccoords[1];
		
		PM.Plugin.Measure2.drawSymbols(pixX, pixY, false);
		$("#mSegTxt").html(_p('Segment') + PM.measureUnits.distance);
	},

	/**
	 * MOUSE MOVE event
	 */
	measure2_mmove: function(e, moveX, moveY) {
		PM.Plugin.Measure2.redrawSegmentTmp(moveX, moveY);
		PM.Plugin.Measure2.calculateLengthTmp(moveX, moveY);
	},

	/**
	 * DOUBLE CLICK event
	 * end measure, calculate polyline length
	 */
	measure2_mdblclick: function() {
		PM.Plugin.Measure2.drawSymbols(PM.ZoomBox.upX, PM.ZoomBox.upY, true);
	},

	/**
	 * Delete last point when the user press key "DEL"
	 */
	measure2_delKeyPress: function() {
		PM.Plugin.Measure2.delLastPoint();
		PM.Plugin.Measure2.reloadData();
	},

	/**
	 * Clear all measures when the user press key "ESC"
	 */
	measure2_EscKeyPress: function() {
		PM.Plugin.Measure2.resetDrawing();
		PM.Plugin.Measure2.reloadData();
	},

	/**
	 * Clear all measures when the user press key "ESC"
	 */
	measure2_Quit: function() {
		PM.Plugin.Measure2.resetDrawing();
	}
});
/******************************************************************************
 *
 * Purpose: Add / update / remove dynamic layers to pmapper
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2009 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

$.extend(PM.Map,
{
	ClientDynamicLayers:
	{
		addOrReplaceLayers: function(layers) {
			this.sendLayers(layers, 'addOrReplace');
		},
		
		removeLayers: function(layers) {
			this.sendLayers(layers, 'remove');
		},
		
		addOrReplaceAndRemoveOtherLayers: function(layers) {
			this.sendLayers(layers, 'replaceAll');
		},
		
		sendLayers: function(layers, action) {
			if (action == 'addOrReplace' || action == 'remove' || action == 'replaceAll') {
				var url = PM_PLUGIN_LOCATION + '/clientdynamiclayers/x_clientDynamicLayers.php';
				var params = SID + '&layers=' + layers + '&action=' + action;
				
				$.ajax({
					url:url,
					data: params,
					type: "POST",
					dataType: "json",
					success: function(response){
						var layerstring = PM.Toc.getLayers();
						
						var refreshToc = false;
						if (response.addedLayers.length > 0) {
							PM.defGroupList = $.merge(eval('["' + layerstring.replace(/,/g, '", "') + '"]'), response.addedLayers);
							$.each(response.addedLayers, function() {
								PM.grouplist[this] = {};
								PM.grouplist[this].name = this;
							});
							if (typeof(delete PM.groupTransparencies) != 'undefined') {
								delete PM.groupTransparencies;
							}
							refreshToc = true;
						}
						else 
							if (response.removedLayers.length > 0) {
								$.each(response.removedLayers, function() {
									delete PM.grouplist[this];
								});
								if (typeof(delete PM.groupTransparencies) != 'undefined') {
									delete PM.groupTransparencies;
								}
								refreshToc = true;
							}
						if (refreshToc) {
							PM.Toc.init();
						}
						
						// Update list in PHP session with new layerstring
						var oldlayerstring = layerstring;
						
						// remove "old" layers:
						$.each(response.removedLayers, function(){
							var search = '';
							search = new RegExp('^\s*' + this + '\s*$');
							layerstring = layerstring.replace(search, '');
							search = new RegExp('^\s*' + this + '\s*,');
							layerstring = layerstring.replace(search, '');
							search = new RegExp(',\s*' + this + '\s*$');
							layerstring = layerstring.replace(search, '');
							search = new RegExp(',\s*' + this + '\s*,');
							layerstring = layerstring.replace(search, ',');
						});
						
						// add new layers:
						$.each(response.activeLayers, function(){
							var found = false;
							var search = '';
							if (!found) {
								search = new RegExp('^\s*' + this + '\s*$');
								found = search.test(layerstring);
							}
							if (!found) {
								search = new RegExp('^\s*' + this + '\s*,');
								found = search.test(layerstring);
							}
							if (!found) {
								search = new RegExp(',\s*' + this + '\s*$');
								found = search.test(layerstring);
							}
							if (!found) {
								search = new RegExp(',\s*' + this + '\s*,');
								found = search.test(layerstring);
							}
							if (!found) {
								layerstring += ',' + this;
							}
						});
						
						// update selected layers:
						layerstring = '&groups=' + layerstring;
						PM.Map.updateSelLayers(PM_XAJAX_LOCATION + 'x_layer_update.php?' + SID + layerstring);
						
/*            
						// Add dyn default layers to PM.defGroupList array
			 			$.merge(PM.defGroupList, response.activeLayers);
*/
						// refresh map
						if (oldlayerstring != layerstring) {
							$("#loading").showv();
							setTimeout('PM.Map.reloadMap(false);', 2000);
						}
						else {
							PM.Map.reloadMap(false);
						}
//						PM.Map.reloadMap(false);
					},
		            error: function (XMLHttpRequest, textStatus, errorThrown) {
		                if (window.console) console.log(errorThrown);
		            }
				});
			}
		}
	}
});
/* compress js files */
// Modified by Thomas Raffin (SIRAP)
// compress js files
// keep the first line!!

// Modified by Jaouad Bennasser (SIRAP)
// Focus and resizing

/**
*Seven Color Picker 1.1.0
*Author: Seven Yu
*E-mail: dofyyu#gmail.com
**/
jQuery.fn.SevenColorPicker = function()
{
	var _SCP_FLAG          = '_I_AM_SCP';
	var _SCP_NUMS_PRE_LINE = 8;   // ????????
	var _SCP_ITEM_SIZE     = 15;  // ????
	var _SCP_ITEM_OFFSET   = 2;   // ????
	var _SCP_OFFSET        = 3;   // ????
	var _SCP_BORDER_WIDTH  = 1;   // ????
    var _SCP_COLORS        = ['ff8080','ffff80','80ff80','00ff80','80ffff','0080ff','ff80c0','ff80ff',
							  'ff0000','ffff00','80ff00','00ff40','00ffff','0080c0','8080c0','ff00ff',
							  '804040','ff8040','00ff00','008080','004080','8080ff','800040','ff0080',
							  '800000','ff8000','008000','008040','0000ff','0000a0','800080','8000ff',
							  '400000','804000','004000','004040','000080','000040','400040','408080',
							  '000000','808000','808040','808080','408080','c0c0c0','400040','ffffff'];
    if(!jQuery.SCP_Selecter)
    {
        var html = '<div><ul>';
        var result = $('<div id="seven_color_selecter" />');
        for(var c in _SCP_COLORS)
            html += '<li><a href="javascript:void(\'#'+_SCP_COLORS[c]+'\');" ref="#'+_SCP_COLORS[c]+'" style="background-color:#'+_SCP_COLORS[c]+';"></a></li>';
		html += '</ul><form style="margin:0;padding:3px;clear:both;text-align:center;">'+
                'HEX: <input id="_seven_color_code" maxlength="7" size="10" style="font:10px verdana" /> '+
                '<input type="submit" value=" OK " style="font:10px verdana" /></form></div>';
        result.html(html);
		$(document).mouseup(function(){result.hide()}).find('body').append(result);
        var setColor = function(col)
        {
            if(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i.test(col))
            {
                col = col.charAt(0) == '#' ? col : '#' + col;
                jQuery.SCP_Active.css('background-color',col);
                jQuery.SCP_Target.val(col).change();
            }
        }
        result.hide().css({'position':'absolute','font':'10px verdana','margin':0,'padding':0})
        .find('div').css({'background-color':'#f2f2f2','border':_SCP_BORDER_WIDTH+'px solid #999','margin':0,'padding':_SCP_OFFSET})
        .width(_SCP_NUMS_PRE_LINE*(_SCP_ITEM_SIZE+_SCP_ITEM_OFFSET*2+_SCP_BORDER_WIDTH*2))
        .find('form').submit(function()
        {
            setColor($(this).children('#_seven_color_code').val());
            jQuery.SCP_Selecter.hide();
            return false;
        }).end()
        .find('ul').css({'margin':0,'padding':0,'list-style':'none'})
        .find('li').css({'margin':0,'padding':0,'float':'left'})
        .find('a').css({'margin':_SCP_ITEM_OFFSET,'padding':0,'display':'block','border':_SCP_BORDER_WIDTH+'px solid #ccc'})
        .width(_SCP_ITEM_SIZE).height(_SCP_ITEM_SIZE)
        .click(function(){$('#_seven_color_code').val($(this).attr('ref')).focus().select();}) //mouseover => click
        .mousedown(function(){setColor($(this).attr('ref'));})
        .mouseover(function(){$(this).css({'border':_SCP_BORDER_WIDTH+'px solid #333'});})
        .mouseout(function(){$(this).css({'border':_SCP_BORDER_WIDTH+'px solid #ccc'});});
        jQuery.SCP_Selecter = result;
        if(jQuery.browser.msie && jQuery.browser.version == '6.0')
            result.find('div').before('<iframe frameborder="0" width="'+result.width()+'" height="'+result.height()+'" style="position:absolute;z-index:-1;"></iframe>');
    }
    return this.each(function()
    {
		var myPicker = $(this).next(':text');
		if(myPicker.attr('ref') != _SCP_FLAG)
		{
			$(this).hide().after(
                $('<input ref="'+_SCP_FLAG+'" />')
                .width(_SCP_ITEM_SIZE).height(_SCP_ITEM_SIZE)
                .click(function() //mouseover => click
                {
                    var offset = $(this).offset();
                    var left = offset.left;
                    var top  = offset.top+$(this).height()+_SCP_BORDER_WIDTH;
                    jQuery.SCP_Target = $(this).prev();
                    jQuery.SCP_Active = $(this);
// Modified by Jaouad Bennasser (SIRAP)
/*                    
                    jQuery.SCP_Selecter.show().css({'left':left,'top':top}).find('#_seven_color_code').val(jQuery.SCP_Target.val()).focus().select();
*/
                    jQuery.SCP_Selecter.show().css({'left':left,'top':top}).find('#_seven_color_code').val(jQuery.SCP_Target.val()).select();
                }).attr('readonly','true')
                .css({'border':_SCP_BORDER_WIDTH+'px solid #999','cursor':'pointer','padding':0,'background-color':$(this).val()})
            );
		}
    });
}
/******************************************************************************
 *
 * Purpose: display infos for layers in pop up
 * Author:  Armin Burger
 *
 ******************************************************************************
 *
 * Copyright (c) 2003-2009 Armin Burger
 *
 * This file is part of p.mapper.
 *
 * p.mapper is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * p.mapper is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

$.extend(PM.Custom,
{

    dlgOptions: {width:500, height:300, resizeable:true, newsize:false, container:'pmDlgContainer'},
    
    showGroupInfo: function(groupId,title,width,height) {
        var groupName = groupId.replace(/ligrp_/, '');
     //   this.dlgOptions.width = width;
     //   this.dlgOptions.height = height;
      //  console.log(this.dlgOptions.width);
        
        var dlg = PM.Dlg.createDnRDlg(this.dlgOptions, groupName , false);
        $.ajax({
            type: "POST",
            url: PM_PLUGIN_LOCATION + '/layerinfo/x_layerinfo.php?group=' + groupName,
            dataType: "html",
            success: function(response) {
                $('#pmDlgContainer_MSG').html(response);
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (window.console) console.log(errorThrown);
            }
        });
    }

});
/******************************************************************************
 *
 * Purpose: Querty Editor plugin
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

$.extend(PM.Plugin,
{
	QueryEditor:
    {
    	dlgOptions: {width:370, height:380, left:250, top:250, resizeable:true, newsize:true, container:'pmQueryEditorContainer', name:'SQL pretraĹľivanje'},
    	dlgOptions1: {width:650, height:250, left:700, top:250, resizeable:true, newsize:true, container:'pmQueryEditorResult', name:'SQL rezultat'},
    	dlgType: 'dynwin',

    	init: function() {
    	/*	if (typeof(PM.ini.pluginsConfig.queryeditor.dlgType) != 'undefined') {
    			this.dlgType = PM.ini.pluginsConfig.queryeditor.dlgType;
    		}*/
    	},

    	openDlg: function() {
			var url = PM_PLUGIN_LOCATION + '/queryeditor/queryeditordlg.phtml';
			var params = SID;

			openAjaxQueryIn(this.dlgType, this.dlgOptions, this.dlgOptions.name, url, params);
			

/*
			PM.ajaxIndicatorShow(false, false);
			$.ajax({
			    url: url,
			    data: params,
		        type: 'POST',
			    dataType: 'html',
			    success: function(response) {
//					PM.ajaxIndicatorHide();
			    	PM.Dlg.createDnRDlg(PM.Plugin.QueryEditor.dlgOptions, PM.Plugin.QueryEditor.dlgOptions.name, false);
					$('#' + PM.Plugin.QueryEditor.dlgOptions.container + '_MSG').html(response);
				},
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    if (window.console) console.log(errorThrown);
                },
				complete: function() {
					PM.ajaxIndicatorHide();
				}
			});
*/
		},
	
		/**
		 * Name of the selected group / layer
		 */
		getLayerName: function() {
			var retVal = "";
			if ($("#queryeditor-layerName").length > 0) {
				var layerName = $("#queryeditor-layerName").val();
				if (layerName) {
					if ((layerName.length > 0) && (layerName != "#")) {
						retVal = layerName;
					}
				}
			}
			return retVal;
		},
	
		/**
		 * Apply the layer that use has chosen
		 * 
		 * If none selected, reset interface
		 * Ask for the available fields for this layer (AJAX request)
		 * Refresh interface
		 */
		setLayerName: function() {
			var layerName = this.getLayerName();
			$("#queryeditor-attributeName").html('');
			$('#queryeditor-attributeType').val('');
			this.setAttributeName();
			this.resetQuery();
			
			if (layerName.length > 0) {
				var url = qeDirUrl + 'x_queryeditor.php';
				var params = SID + '&operation=getattributes&layername=' + layerName;
				PM.ajaxIndicatorShow(false, false);
				$.ajax({
					url: url,
					data: params,
					dataType: "json",
					success: function(response) {
						if ($('#queryeditor-attributeName').length) {
							var options = '<option value="#"></option>\n';
							var attributes = response.attributes;
							$.each(attributes, function() {
								if (this['field'] && this['header']) {
									options += '<option value=\"' + this['field'] + '\" label=\"' + this['header'] + '\">' + this['header'] + '</option>\n';
								}
							});
							$("#queryeditor-attributeName").html(options);
							$("#queryeditor-attributeName").val("");
						}
//						PM.ajaxIndicatorHide();
					},
	                error: function (XMLHttpRequest, textStatus, errorThrown) {
	                    if (window.console) console.log(errorThrown);
	                },
					complete: function() {
						PM.ajaxIndicatorHide();
					}
				});
			}
		},
	
		/**
		 * Real name of the selected field
		 */
		getAttributeRealName: function() {
			var retVal = "";
			if ($("#queryeditor-attributeName").length > 0) {
				var indicatorRealName = $("#queryeditor-attributeName").val();
				if (indicatorRealName) {
					if ((indicatorRealName.length > 0) && (indicatorRealName != "#")) {
						retVal = indicatorRealName;
					}
				}
			}
			return retVal;
		},
	
		/**
		 * Readable name of the selected field (=header)
		 */
		getAttributeReadName: function() {
			var retVal = "";
			var elemTmp = document.getElementById("queryeditor-attributeName");
			if (typeof(elemTmp) != 'undefined' && elemTmp) {
				if (elemTmp.selectedIndex > 0) {
					var indicatorReadName = elemTmp.options[elemTmp.selectedIndex].text;
					if (typeof(indicatorReadName) != 'undefined') {
						retVal = indicatorReadName;
					}
				}
			}
			return retVal;
		},
	
		/**
		 * Apply the chosen field
		 *
		 * Refresh interface and call setAttributeType
		 */
		setAttributeName: function() {
			var attrRealName = this.getAttributeReadName();
			$('#queryeditor-attributeType').val('');
			$('#queryeditor-attributeType').attr('disabled','disabled');
			this.setAttributeType();
	
			if (attrRealName) {
				if (attrRealName.length > 0) {
					$('#queryeditor-attributeType').removeAttr('disabled');
				}
			}
		},
	
		/**
		 * Apply the field type
		 *
		 * Refresh interface
		 */
		setAttributeType: function() {
			$('#queryeditor-attributeValue').val('');
			//$('#queryeditor-attributeValue').attr('disabled','disabled');
			$('.queryeditor-attributeCriteriaComparison').hide();
			$('#queryeditor-attributeCriteriaComparisonNone').parent().show();
			
			var attrType = $('#queryeditor-attributeType').val();
			if (attrType) {
				$('#queryeditor-attributeCriteriaComparisonNone').parent().hide();
				if (attrType == 'N') {
					$('#queryeditor-attributeCriteriaComparisonNum').parent().show();
					$('#queryeditor-attributeValue').removeAttr('disabled');
				} else if (attrType == 'S') {
					$('#queryeditor-attributeCriteriaComparisonTxt').parent().show();
					$('#queryeditor-attributeValue').removeAttr('disabled');
				} else {
					$('#queryeditor-attributeCriteriaComparisonNone').parent().show();
				}
			}
		},
	
		/**
		 * OnKeyPress event
		 * 
		 * Avoid default ENTER key behaviour:
		 * - if ENTER is press, then apply the attribute value (= call setAttributeValue).
		 * - if an other key is press, the onkeyup will call changeAttributeValue.
		 */
		attributeValueKeyPress: function(e) {
			var key;
			// IE :
			if (window.event) {
				key = window.event.keyCode;
			} else { // Firefox
				key = e.which;
			}
	
			// ENTER key :
			if (key == 13) {
				setAttributeValue();
				return false;
			} else {
				return true;
			}
		},
	
		/**
		 * OnKypUp event
		 *
		 * Enable on disable the "add" button
		 */
		changeAttributeValue: function() {
			var attrval = $('#queryeditor-attributeValue').val();
			var btnEnable = false;
			if (attrval) {
				if (attrval.length > 0) {
					btnEnable = true;
				}
			}
			//btnEnable ? $('#queryeditor-attributeBtnAdd').removeAttr('disabled') : $('#queryeditor-attributeBtnAdd').attr('disabled','disabled') ;
		},
	
		/**
		 * Apply the attribute value
		 *
		 * Generate the new query part (depending on the field type and comparison operator)
		 * Add the query part in the textarea
		 * Reset the attribute name and then refresh the interface by calling setAttributeName
		 */
		setAttributeValue: function() {
			var bContinue = true;
			var queryPartToAdd = '';
	
			if (bContinue) {
				bContinue = false;
				var attrName = this.getAttributeReadName();
				if (attrName) {
					if (attrName.length > 0) {
						queryPartToAdd +=  attrName ;
						bContinue = false;
						var attrVal = $('#queryeditor-attributeValue').val();
						if (attrVal) {
							var attrType = 'N';
							if (attrType) {
								bContinue = true;
								if (attrType == 'N') {
									var attrOperator = $('#queryeditor-attributeCriteriaComparisonNum').val();
									if (attrOperator) {
										if (attrOperator == 'equal') {
											queryPartToAdd += " = '" + attrVal + "'" ;
										} else if (attrOperator == 'inferiororequal') {
											queryPartToAdd += ' <= ' + attrVal;
										} else if (attrOperator == 'superiororequal') {
											queryPartToAdd += ' >= ' + attrVal;
										} else if (attrOperator == 'strictlyinferior') {
											queryPartToAdd += ' < ' + attrVal;
										} else if (attrOperator == 'strictlysuperior') {
											queryPartToAdd += ' > ' + attrVal;
										} else if (attrOperator == 'different') {
											queryPartToAdd += ' <> ' + attrVal;
										} else if (attrOperator == 'LIKE') {
											queryPartToAdd += " LIKE '%" + attrVal + "%'";
										} else {
											bContinue = false;
										}
									}
								}  else {
									bContinue = false;
								}
							}
						}
					}
				}
			}
	
			if (bContinue) {
				this.addToQuery(queryPartToAdd);
				//$('#queryeditor-attributeBtnAdd').attr('disabled','disabled');
				$('#queryeditor-attributeName').val('');
				this.setAttributeName();
			}
		},
	
		/**
		 * Apply operator choice: add it to query
		 */
		setOperator: function(id) {
			var op = '';
			switch (id) {
				case 'queryeditor-operatorBtnOpenBracket':
					op = '(';
					break;
				case 'queryeditor-operatorBtnCloseBracket':
					op = ')';
					break;
				case 'queryeditor-operatorBtnNot':
					op = 'NOT';
					break;
				case 'queryeditor-operatorBtnAnd':
					op = 'AND';
					break;
				case 'queryeditor-operatorBtnOr':
					op = 'OR';
					break;
				default:
					break;
			}
			this.addToQuery(op);
		},
	
		/**
		 * Add text to the current query
		 */
		addToQuery: function(queryPartToAdd) {
			var currentQuery = $('#queryeditor-generatedQuery').val();
			if (currentQuery) {
				if (currentQuery.length > 0 ){
					queryPartToAdd = currentQuery + '\n' + queryPartToAdd;
				}
			}
			this.updateQuery(queryPartToAdd);
		},
	
		/**
		 * Delete the urrent query
		 */
		resetQuery: function() {
			this.updateQuery('');
		},
	
		/**
		 * Update query
		 *
		 * Change the query with the parameter value
		 * Refresh interface by calling queryHasBeenUpdated
		 */
		updateQuery: function(query) {
			$('#queryeditor-generatedQuery').val(query);
			this.queryHasBeenUpdated();
		},
	
		/**
		 * Refresh interface depending on the current query content
		 */
		queryHasBeenUpdated: function() {
			$('#queryeditor-btnReset').attr('disabled','disabled');
			$('#queryeditor-btnApply').attr('disabled','disabled');
		//	$('#queryeditor-operatorGroup2 input').attr('disabled','disabled');
	
			var currentQuery = $('#queryeditor-generatedQuery').val();
			if (currentQuery) {
				if (currentQuery.length > 0) {
					$('#queryeditor-btnReset').removeAttr('disabled');
					$('#queryeditor-btnApply').removeAttr('disabled');
					//$('#queryeditor-operatorGroup2 input').removeAttr('disabled');
				}
			}
		},
	
		/**
		 * Reset interface
		 */
		reset: function() {
			$('#queryeditor-LayerName').val('');
			this.setLayerName();
			this.resetQuery();
		},
	
		/**
		 * Cancel (close the query window)
		 */
		cancel: function() {
			if ($('#' + this.dlgOptions.container).length > 0) {
				$('#' + this.dlgOptions.container + ' .jqmClose').click();
			}
		},
	
		/**
		 * Execute the current query
		 *
		 * Use standard getQueryResult function to show result, select and zoom to selected...
		 */
		apply: function() {
			var layerName = this.getLayerName();
			if (layerName.length > 0) {
				var query = $('#queryeditor-generatedQuery').val();
				query = query.replace('%','%25');
				if (query) {
					if (query.length > 0) {
						var url = qeDirUrl + 'x_queryeditor.php';
						var params = SID + '&operation=query&layername=' + layerName + '&layerType=shape&query=' + query;
						var urltmp = '';
						openAjaxQueryIn(this.dlgType, this.dlgOptions1, this.dlgOptions1.name, url, params);
						/*
						if (document.URL.indexOf('queryeditor') > 0) {
							opener.PM.Query.getQueryResult(url, params);
						} else {
							PM.Query.getQueryResult(url, params);
							//		        	this.cancel();
						}*/
					}
				}
			}
		},
		
		applyResult: function(aId, aLayerName) {
			//alert(aId);
			var url = PM_PLUGIN_LOCATION + '/queryeditor/x_queryeditor.php';
			$.ajax({
					url: url,
					data: 'operation=updateMap&aId=' + aId + '&layername=' + aLayerName,
					dataType: "html",
					success: function(response) {
						var mapurl = PM_XAJAX_LOCATION + 'x_load.php?mode=map&zoom_type=zoomextent&extent=' + response;							
						PM.Map.updateMap(mapurl);
					}
				});
		}
		
		
		
		

    }
});

/******************************************************************************
 *
 * Purpose: common js function for pmapper plugins
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

function openResultwin(winurl) {
    try {
        if (PM.queryResultLayout == 'tree') {
            var winw = 300;
            var winh = 450;
        } else {
            var winw = 500;
            var winh = 200;
        }
    } catch(e) {
        var winw = 500;
        var winh = 200;
    }
    
    var w = window.open(winurl, 'resultwin', 'width=' + winw + ',height=' + winh + ',status=yes,resizable=yes,scrollbars=yes');
    w.focus();
    return w;
}

// typewin can be the id of the element like "frame" (with "#")
function openAjaxQueryIn(typewin, dlgOptions, dlgTitle, url, params) {
	if (typewin == 'window') {
		if (url.indexOf('?') == -1) {
			url += '?';
		} else {
			url += '&';
		}
		url += 'addjsandcss=true';
		if (params) {
			url += '&' + params;
		}
		openResultwin(url);
	} else {
		if (url.indexOf('?') > 0) {
			params += (params ? '&' : '') + url.substr(url.indexOf('?') + 1);
		}
		
		PM.ajaxIndicatorShow(false, false);
		$.ajax({
		    url: url,
		    data: params,
	        type: 'POST',
		    dataType: 'html',
		    success: function(response) {
//				PM.ajaxIndicatorHide();
				var resContainer = '';
				if (typewin == 'dynwin') {
					if (!dlgOptions.width) {
						dlgOptions.width = 450;
					}
					if (!dlgOptions.height) {
						dlgOptions.height = 250;
					}
					if (!dlgOptions.container) {
						dlgOptions.container = 'pmDlgContainer';
					}
					PM.Dlg.createDnRDlg(dlgOptions, dlgTitle, false);
					resContainer = '#' + dlgOptions.container + '_MSG';
				} else {
					if (typewin == 'frame' && $('#infoFrame').length > 0) {
						resContainer = '#infoFrame';
					} else if (typewin[0] == '#' && $(typewin).length > 0) { 
						resContainer = typewin;
					}
				}
				$(resContainer).html(response);
			},
			error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (window.console) console.log(errorThrown);
            },
			complete: function() {
				PM.ajaxIndicatorHide();
			}
		});
	} 
}

/**
 * Convert HEXA color to RGB 
 */
function convertHexToRGB(hexColor){
	var r, g, b;
	if (hexColor == '') {
		r = -1;
		g = -1;
		b = -1;
	} else {
	    r = HexToR(hexColor);
	    g = HexToG(hexColor);
	    b = HexToB(hexColor);
	}
	// Do not change the way to add "," and space because of js compression algorythm...
    var rgb = r.toString() + "," + " " + g.toString() + "," + " " + b.toString();

    return rgb;
}
function HexToR(h) {
	return parseInt((cutHex(h)).substring(0,2),16);
} 
function HexToG(h) {
	return parseInt((cutHex(h)).substring(2,4),16);
} 
function HexToB(h) {
	return parseInt((cutHex(h)).substring(4,6),16);
} 
function cutHex(h) {
	return (h.charAt(0)=="#") ? h.substring(1,7):h;
}  

/**
 * Convert RGB color to HEXA 
 */
function convertRgbToHex(num) {
	var decToHex="";
	var arr = [];
	var numStr = new String();
	numStr = num;

	arr = numStr.split(",");

	for(var i=0;i<3;i++){
		var hexArray = new Array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" );
		var code1 = Math.floor(arr[i] / 16);
		var code2 = arr[i] - code1 * 16;
		decToHex += hexArray[code1];
		decToHex += hexArray[code2];
	}
	return (decToHex);
}	

function generateColor(iClass, nbClass, hexColor1, hexColor2) {
	var r1 = HexToR(hexColor1);
    var g1 = HexToG(hexColor1);
    var b1 = HexToB(hexColor1);
	var r2 = HexToR(hexColor2);
    var g2 = HexToG(hexColor2);
    var b2 = HexToB(hexColor2);
	var nb = (nbClass > 1) ? nbClass - 1 : 1;
	var rOffset = Math.round((r2 - r1)/nb);
	var gOffset = Math.round((g2 - g1)/nb);
	var bOffset = Math.round((b2 - b1)/nb);
	var r = Math.max(Math.min(255, r1 + iClass * rOffset),0);
	var g = Math.max(Math.min(255, g1 + iClass * gOffset),0);
	var b = Math.max(Math.min(255, b1 + iClass * bOffset),0);

	var hexaColor = convertRgbToHex(r + ',' + g + ',' + b);
    
	return hexaColor;
}

/** function used to upper the first letter of a word
 * parameters: word  
 * @return: Word
 */
function upperWord(word) {
    var w = word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
    return w;
}

/**
 * 
 * get PM.Plugin[............] object
 * return null if error
 * 
 * @param strIn string (with "." separator).
 * 
 * For instance : "drawing" will return PM.Plugin.drawing object
 */
function getPMPluginObjFromString(strIn) {
	var retPluginObj = null;
	
	var retPluginObjTmp = PM.Plugin;
	var pluginNameCltArray = strIn.split(".");
	var ok = false;
	$.each(pluginNameCltArray, function(index, value) {
		var objTmp = retPluginObjTmp[value];
		if (typeof(objTmp) != "undefined") {
			retPluginObjTmp = objTmp;
			ok = true;
		} else {
			ok = false;
		}
		return ok;
	});
	if (ok) {
		retPluginObj = retPluginObjTmp;
	}
	
	return retPluginObj;
}

$.extend(PM.Plugin,
{
	UploadFile:
    {
    	dlgType: 'dynwin',		
    	dlgOptions: {width:700, height:300, left:300, top:100, resizeable:false, newsize:true, container:'pmkatasterSearchContainer2', name:'Rezultati'},
    	
    		
    	init: function() {
			$("#tb_identifyAdd").click(function(){
				PM.Plugin.DocToolTip.init();
			});
    		
    	},


    
		openDlg: function(koPar, mx, my) {
			var coord = new Point(mx, my);

			// Convert points to current scale
			coord = PM.Draw.toGeoPoint(coord);
			var mx = Math.round(coord.x);
			var my = Math.round(coord.y);
			
			var url = PM_PLUGIN_LOCATION + '/_uploadFiles/uploadDialog.phtml';
			var params = SID;
			params = params + '&koPar=' +  koPar + '&mx=' + mx + '&my=' + my;
			parcele = new Array();
			parcele.push(koPar);
			openAjaxQueryIn(this.dlgType, this.dlgOptions, 'PostojeÄ‡i dokumenti', url, params);
			
		},
		
	
			
	
		
		uploader: function(xy) {
	        var pos = xy.split('+');
	        var mx = pos[0]; 
	        var my = pos[1];

	        PM.ajaxIndicatorShow(mx, my);
	        var url = PM_XAJAX_LOCATION + 'x_info.php';  
	        var params = SID + '&mode=query&idPar=1&imgxy='+xy; 
	        $.ajax({
					url: url,
					data: params,
					//dataType: "json",
					success: function(response) {	
							PM.Plugin.UploadFile.openDlg(response, mx, my);
							if (PM.Plugin.DocToolTip.status == 0) PM.Plugin.DocToolTip.init();
							PM.Plugin.DocToolTip.refreshMap();
					},
					complete: function() {
						PM.ajaxIndicatorHide();
					}
				});
   		 }

    }
});
/******************************************************************************
 *
 * Purpose: common js function for pmapper plugins
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

function openResultwin(winurl) {
    try {
        if (PM.queryResultLayout == 'tree') {
            var winw = 300;
            var winh = 450;
        } else {
            var winw = 500;
            var winh = 200;
        }
    } catch(e) {
        var winw = 500;
        var winh = 200;
    }
    
    var w = window.open(winurl, 'resultwin', 'width=' + winw + ',height=' + winh + ',status=yes,resizable=yes,scrollbars=yes');
    w.focus();
    return w;
}

// typewin can be the id of the element like "frame" (with "#")
function openAjaxQueryIn(typewin, dlgOptions, dlgTitle, url, params) {
	if (typewin == 'window') {
		if (url.indexOf('?') == -1) {
			url += '?';
		} else {
			url += '&';
		}
		url += 'addjsandcss=true';
		if (params) {
			url += '&' + params;
		}
		openResultwin(url);
	} else {
		if (url.indexOf('?') > 0) {
			params += (params ? '&' : '') + url.substr(url.indexOf('?') + 1);
		}
		
		PM.ajaxIndicatorShow(false, false);
		$.ajax({
		    url: url,
		    data: params,
	        type: 'POST',
		    dataType: 'html',
		    success: function(response) {
//				PM.ajaxIndicatorHide();
				var resContainer = '';
				if (typewin == 'dynwin') {
					if (!dlgOptions.width) {
						dlgOptions.width = 450;
					}
					if (!dlgOptions.height) {
						dlgOptions.height = 250;
					}
					if (!dlgOptions.container) {
						dlgOptions.container = 'pmDlgContainer';
					}
					PM.Dlg.createDnRDlg(dlgOptions, dlgTitle, false);
					resContainer = '#' + dlgOptions.container + '_MSG';
				} else {
					if (typewin == 'frame' && $('#infoFrame').length > 0) {
						resContainer = '#infoFrame';
					} else if (typewin[0] == '#' && $(typewin).length > 0) { 
						resContainer = typewin;
					}
				}
				$(resContainer).html(response);
			},
			error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (window.console) console.log(errorThrown);
            },
			complete: function() {
				PM.ajaxIndicatorHide();
			}
		});
	} 
}

/**
 * Convert HEXA color to RGB 
 */
function convertHexToRGB(hexColor){
	var r, g, b;
	if (hexColor == '') {
		r = -1;
		g = -1;
		b = -1;
	} else {
	    r = HexToR(hexColor);
	    g = HexToG(hexColor);
	    b = HexToB(hexColor);
	}
	// Do not change the way to add "," and space because of js compression algorythm...
    var rgb = r.toString() + "," + " " + g.toString() + "," + " " + b.toString();

    return rgb;
}
function HexToR(h) {
	return parseInt((cutHex(h)).substring(0,2),16);
} 
function HexToG(h) {
	return parseInt((cutHex(h)).substring(2,4),16);
} 
function HexToB(h) {
	return parseInt((cutHex(h)).substring(4,6),16);
} 
function cutHex(h) {
	return (h.charAt(0)=="#") ? h.substring(1,7):h;
}  

/**
 * Convert RGB color to HEXA 
 */
function convertRgbToHex(num) {
	var decToHex="";
	var arr = [];
	var numStr = new String();
	numStr = num;

	arr = numStr.split(",");

	for(var i=0;i<3;i++){
		var hexArray = new Array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" );
		var code1 = Math.floor(arr[i] / 16);
		var code2 = arr[i] - code1 * 16;
		decToHex += hexArray[code1];
		decToHex += hexArray[code2];
	}
	return (decToHex);
}	

function generateColor(iClass, nbClass, hexColor1, hexColor2) {
	var r1 = HexToR(hexColor1);
    var g1 = HexToG(hexColor1);
    var b1 = HexToB(hexColor1);
	var r2 = HexToR(hexColor2);
    var g2 = HexToG(hexColor2);
    var b2 = HexToB(hexColor2);
	var nb = (nbClass > 1) ? nbClass - 1 : 1;
	var rOffset = Math.round((r2 - r1)/nb);
	var gOffset = Math.round((g2 - g1)/nb);
	var bOffset = Math.round((b2 - b1)/nb);
	var r = Math.max(Math.min(255, r1 + iClass * rOffset),0);
	var g = Math.max(Math.min(255, g1 + iClass * gOffset),0);
	var b = Math.max(Math.min(255, b1 + iClass * bOffset),0);

	var hexaColor = convertRgbToHex(r + ',' + g + ',' + b);
    
	return hexaColor;
}

/** function used to upper the first letter of a word
 * parameters: word  
 * @return: Word
 */
function upperWord(word) {
    var w = word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
    return w;
}

/**
 * 
 * get PM.Plugin[............] object
 * return null if error
 * 
 * @param strIn string (with "." separator).
 * 
 * For instance : "drawing" will return PM.Plugin.drawing object
 */
function getPMPluginObjFromString(strIn) {
	var retPluginObj = null;
	
	var retPluginObjTmp = PM.Plugin;
	var pluginNameCltArray = strIn.split(".");
	var ok = false;
	$.each(pluginNameCltArray, function(index, value) {
		var objTmp = retPluginObjTmp[value];
		if (typeof(objTmp) != "undefined") {
			retPluginObjTmp = objTmp;
			ok = true;
		} else {
			ok = false;
		}
		return ok;
	});
	if (ok) {
		retPluginObj = retPluginObjTmp;
	}
	
	return retPluginObj;
}

/******************************************************************************
 *
 * Purpose: Reload timing map for pmapper framework
 * Author:  Walter Lorenzetti, gis3w, lorenzetti@gis3w.it
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 gis3w
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

$.extend(PM.Plugin,
{
    DocToolTip:
    {
       status: 0,
       init: function() {
      // 	alert(PM.Plugin.DocToolTip.status);
       		if (PM.Plugin.DocToolTip.status == 1) {
       			$('#GeoDocs').fadeOut('slow');
       			$('#GeoDocs').empty();
				$('#img_identifyAdd').attr("src","images/buttons/default/identifyAdd_off.gif");
       			PM.Plugin.DocToolTip.status = 0;
       		} else {
				$('#img_identifyAdd').attr("src","images/buttons/default/identifyAdd_on.gif");
       			PM.Plugin.DocToolTip.status = 1;
       			this.refreshMap();	
       		}
        },

        docView: function(aId) {
        	$('#show'+aId).remove();
        	
        	$.ajax({
         		url: "plugins/DocsViewPlugin/ajax.docsView_showDoc.php", 
         		type: 'POST',
         		data: 'id=' + aId,     					
	         		success: function(data){
				        //$('#doc'+aId).append('<div id=show'+ aId +' style="color:#ffffff;width:120px;">'+data+'</div>');
						$('#doc'+aId).append(data);
						$('#doc'+aId).css("z-index", "3000");
						$('#doc'+aId).mouseout(function(){$('#show'+aId).hide();});
				        $('#show'+aId).hide();
				        $('#show'+aId).fadeIn('slow');	
					}
         		});
        },
        
        docHide: function(aId) {
        	$('#show'+aId).delay(1000).fadeOut('slow');
        	$('#show'+aId).remove();
        },
		
		showLink: function(aId) {
			alert(aId);
			return false;
		},
		
        empty: function() {
			$('#GeoDocs').empty();
		},
        
        refreshMap: function() {
        	if (PM.Plugin.DocToolTip.status == 1) {
        		$('#GeoDocs').empty();
        		$('#GeoDocs').fadeIn('fast');
	        	$.ajax({
         		url: "plugins/DocsViewPlugin/ajax.docsView_Load.php", 
         		type: 'POST',
         		data: 'x=' + PM.minx_geo + '&y=' + PM.maxy_geo + '&dx=' + PM.xdelta_geo + '&dy=' + PM.ydelta_geo + '&width=' + $('#mapImg').width() + '&height=' + $('#mapImg').height(),
	         		success: function(data){
	         			eval(data);
	      			}
         		});  	   		
        	}
        }
        
    }
});
/******************************************************************************
 *
 * Purpose: Reload timing map for pmapper framework
 * Author:  Walter Lorenzetti, gis3w, lorenzetti@gis3w.it
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 gis3w
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

$.extend(PM.Plugin,
{
    katasterComment:
    {
       dlgType: 'dynwin',		
    	dlgOptions: {width:300, height:200, left:300, top:100, resizeable:false, newsize:true, container:'pmkatasterComment', name:'Komentar'},
    	
       status: 0,
       activeComment: 0,
       	 
       init: function() {
       
       		if (PM.Plugin.katasterComment.status == 1) {
				//PM.ZoomBox.mouseDrag = true;
       			$('#GeoComment').fadeOut('slow');
       			$('#GeoComment').empty();
				$('#img_makeComment').attr("src","images/buttons/default/makeComment_off.gif");
       			PM.Plugin.katasterComment.status = 0;
       			
       		} else {
				$('#img_makeComment').attr("src","images/buttons/default/makeComment_on.gif");
				//PM.ZoomBox.mouseDrag = false;
       			PM.Plugin.katasterComment.status = 1;
       			this.refreshMap();	
       		}
       			//alert(PM.Plugin.katasterComment.status);
        },

        
       
        photoView: function(aId) {
        	$('#showC'+aId).remove();
        	
        	
        	$.ajax({
         		url: "plugins/_katasterComment/ajax.photoViewPlugin_showIImg.php", 
         		type: 'POST',
         		data: 'idPhoto=' + aId,     					
	         		success: function(data){
				        	$('#komentar'+aId).append('<div id=showC'+ aId +' style="z-index:401;color:#ffffff;width:150px;height:150px">'+data+'</div>');	
				        	$('#showC'+aId).hide();
				        	$('#showC'+aId).fadeIn('slow');	
					}
         		});  	   		
        		
        },
        
        photoHide: function(aId) {
        	$('#showC'+aId).fadeOut('slow');
        	$('#showC'+aId).remove();
        },
        
        
        refreshMap: function() {
        	
        	$("#jqContextMenu").hide();
        	$("#jqContextMenuShadow").hide();
        	
        	if (PM.Plugin.katasterComment.status == 1) {
        		//alert($('#mapImg').src());
        		$('#GeoComment').empty();
        		$('#GeoComment').fadeIn('fast');
	        	$.ajax({
         		url: "plugins/_katasterComment/ajax.photoViewPlugin_Load.php", 
         		type: 'POST',
         		data: 'x=' + PM.minx_geo + '&y=' + PM.maxy_geo + '&dx=' + PM.xdelta_geo + '&dy=' + PM.ydelta_geo + '&image=' + $('#mapImg').src(),     					
	         		success: function(data){
	         			eval(data);
	      			}
         		});  	   		
        	}
        },
        
     
        AddComment : function() {
        	x = $('#xcoord').html();
        	y = $('#ycoord').html();
        	
        	var url = PM_PLUGIN_LOCATION + '/_katasterComment/katasterCommentDialog.phtml';
			var params = SID + '&x=' + x + '&y=' + y;
			
			openAjaxQueryIn(this.dlgType, this.dlgOptions, 'Komentarji', url, params);
        	
        	
        },

        
        EditComment : function() {
        	
        	if (this.activeComment == 0) return;
        	var url = PM_PLUGIN_LOCATION + '/_katasterComment/katasterCommentDialog.phtml';
			var params = SID + '&editID=' + this.activeComment;
			
			openAjaxQueryIn(this.dlgType, this.dlgOptions, 'Komentarji', url, params);
        	
        	
        },
        
        SaveNewComment : function(a) {
        	if (a == 1) action = "Add"; else action = "Save";
        	$.ajax({
         		url: "plugins/_katasterComment/ajax.CommentAction.php", 
         		type: 'POST',
         		data: 'action=' + action + '&text=' + $("#KatasterComment").val() + '&x=' + $('#xComment').val() + '&y=' + $('#yComment').val() + '&id_comment=' + $('#idComment').val(),     					
	         		success: function(data){
	         			$('#pmkatasterComment').hide();
	         			PM.Plugin.katasterComment.refreshMap();	
	      			}
         		});  	   		
        	
        },
        DeleteComment : function() {
        		if (this.activeComment == 0) return;
        	$.ajax({
         		url: "plugins/_katasterComment/ajax.CommentAction.php", 
         		type: 'POST',
         		data: 'deleteId=' + this.activeComment,     					
	         		success: function(data){
	         			PM.Plugin.katasterComment.refreshMap();	
	      			}
         		});  	   		
        }
        
    }
});


/******************************************************************************
 *
 * Purpose: Querty Editor plugin
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/


$.extend(PM.Plugin,
{
	katasterSearch:
    {
    	dlgOptions: {width:700, height:470, left:50, top:50, resizeable:false, newsize:true, container:'pmkatasterSearchContainer', name:'Iskanje po katastru'},
    	dlgType: 'dynwin',		
    	dlgOptions2: {width:700, height:250, left:50, top:50, resizeable:false, newsize:true, container:'pmkatasterSearchContainer2', name:'Rezultati'},
    	
    		
    	init: function() {
    		
    	},

    	openDlg: function() {
			var url = PM_PLUGIN_LOCATION + '/_katasterSearch/katasterSearch.phtml';
			var params = SID;
			openAjaxQueryIn(this.dlgType, this.dlgOptions, this.dlgOptions.name, url, params);
			$.oznaceni_idji = '';
			
		},
	
		openDlg2: function() {
			var url = PM_PLUGIN_LOCATION + '/_katasterSearch/katasterPosition.phtml';
			var params = SID;
			params = params + '&idji=' +  $.oznaceni_idji;
			
			openAjaxQueryIn(this.dlgType, this.dlgOptions2, this.dlgOptions2.name, url, params);
			
		},
		
		openDlg3: function(koPar) {
			var url = PM_PLUGIN_LOCATION + '/_katasterSearch/katasterPosition.phtml';
			var params = SID;
			params = params + '&koPar=' +  koPar;
			if ($('#pmkatasterSearchContainer2').is(":visible")) {
				parcele.push(koPar);
			//	console.log(parcele);
				$.ajax({
					url: qeDirUrl + 'x_tableAddParcela.php',
					data: params,
					//dataType: "json",
					success: function(response) {
						eval(response)	
					}
				});			
											
				
			} else {
				parcele = new Array();
				parcele.push(koPar);
				openAjaxQueryIn(this.dlgType, this.dlgOptions2, this.dlgOptions2.name, url, params);
			}
				
			
		},
		
		saveChecked: function(obj) {
			
			if (obj.checked) $.oznaceni_idji = $.oznaceni_idji + ',' + obj.value;
				else $.oznaceni_idji = $.oznaceni_idji + ',-' + obj.value;
				
		},
		
		saveAllChecked: function(obj) {
			if (obj.checked) {
				for (i = 1; i < $('#numberCheckItems').val(); i++) {
					$.oznaceni_idji = $.oznaceni_idji + ',' + $('#search_checker' + i).val();
					$('#search_checker' + i).attr('checked','checked');
				}
			} else {
				for (i =1; i < $('#numberCheckItems').val(); i++) {
					$('#search_checker' + i).attr('checked','');
					$.oznaceni_idji = $.oznaceni_idji + ',-' + $('#search_checker' + i).val();
				}
			}
		},
		
		viewChecked: function() {
			var url = qeDirUrl + 'x_katasterPosition.php';
			var params = SID;
			params = params + '&idji=' +  $.oznaceni_idji;
			$('#ginput_Katastar').attr('checked',true); PM.Toc.setlayers('Katastar',false);
				
			
			$.ajax({
					url: url,
					data: params,
					//dataType: "json",
					success: function(response) {
						if (response != '0') {
							resp = response.split(';');
							var mapurl = PM_XAJAX_LOCATION + 'x_load.php?mode=map&zoom_type=zoomextent&extent=' + resp[0].replace(/^\s+|\s+$/g,"") + '&selectParcela=' + resp[1];
							
							PM.Map.updateMap(mapurl);
							PM.Plugin.katasterSearch.openDlg2();
							HideContainer('pmkatasterSearchContainer','Iskalnik po katastru');
						} else alert('Ni prikaza');
					},
					complete: function() {
						PM.ajaxIndicatorHide();
						
					}
				});			
		},	
		
		viewParcela: function(id) {
			var url = qeDirUrl + 'x_katasterPosition.php';
			var params = SID;
			params = params + '&idji=' +  id;
			//this.openDlg2();
		
			$.ajax({
					url: url,
					data: params,
					//dataType: "json",
					success: function(response) {
						if (response != '0') {
							resp = response.split(';');
							var mapurl = PM_XAJAX_LOCATION + 'x_load.php?mode=map&zoom_type=zoomextent&extent=' + resp[0].replace(/^\s+|\s+$/g,"") + '&selectParcela=' + resp[1];
						
							PM.Map.updateMap(mapurl);
							
						} else alert('Ni prikaza');
					},
					complete: function() {
						PM.ajaxIndicatorHide();
						
					}
				});			
		},	
			
		/**
		 * Apply the layer that use has chosen
		 * 
		 * If none selected, reset interface
		 * Ask for the available fields for this layer (AJAX request)
		 * Refresh interface
		 */
		runSearch: function() {
		
			$("#queryeditor-attributeName").html('');
			$('#queryeditor-attributeType').val('');
			$.oznaceni_idji = '';
			
				var url = qeDirUrl + 'x_katasterSearch.php';
				var params = SID;
					params = params + '&naziv=' + $('#katasterSearch-attributeOseba').val();
					params = params + '&ParStevilka=' + $('#katasterSearch-attributeParcela').val();
					params = params + '&zkv=' + $('#katasterSearch-attributeZKV').val();
					params = params + '&ko=' + $('#katasterSearch-attributeKO').val();
					params = params + '&vrstaRabe=' + $('#katasterSearch-attributeOpisVrstaRabe').val();
					params = params + '&poslist=' + $('#katasterSearch-attributePosList').val();
					
					
				PM.ajaxIndicatorShow(false, false);
				$.ajax({
					url: url,
					data: params,
					//dataType: "json",
					success: function(response) {	
							$("#katasterSearch-resultTable").html(response);
							$("#katasterSearch-resultTableButton").html("<input id=\"katasterSearch-moreButton\"  type=button  value=\"PrikaĹľi\" onclick=\"javascript:PM.Plugin.katasterSearch.viewChecked()\" />");
					},
					complete: function() {
						PM.ajaxIndicatorHide();
					}
				});
				
					/*
				var queryurl = PM_XAJAX_LOCATION + 'x_info.php';
				
				var params = SID;
					 
					params = params + '&mode=search';
					params = params + '&parcela=10';
					params = params + '&searchitem=Katastar';
					params = params + '&sifko=0617';
				PM.Query.getQueryResult(queryurl, params);*/
			
		},
	
		showOwner: function(xy) {
	        var pos = xy.split('+');
	        var mx = pos[0]; 
	        var my = pos[1];

	        PM.ajaxIndicatorShow(mx, my);
	        var url = PM_XAJAX_LOCATION + 'x_info.php';  
	        var params = SID + '&mode=query&idPar=2' + '&imgxy='+xy; // + layerstring;
	        $.ajax({
					url: url,
					data: params,
					//dataType: "json",
					success: function(response) {	
							PM.Plugin.katasterSearch.openDlg3(response);
							
							var mapurl=PM_XAJAX_LOCATION+'x_load.php?'+SID+'&zoom_type=zoompoint&action=addSelection&selectionLayer=katastar&condition=\'[id_par]\' eq \'' + response + '\'';
							
							PM.Map.updateMap(mapurl);
					},
					complete: function() {
						PM.ajaxIndicatorHide();
					}
				});
   		 },
   		 
   		 exportExcel: function () {
   		 	window.open('GeofotoModifications/exportExcel.php?koPar=' + parcele.join(','));
   		 }
	
		
		

    }
});
/******************************************************************************
 *
 * Purpose: common js function for pmapper plugins
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/

function openResultwin(winurl) {
    try {
        if (PM.queryResultLayout == 'tree') {
            var winw = 300;
            var winh = 450;
        } else {
            var winw = 500;
            var winh = 200;
        }
    } catch(e) {
        var winw = 500;
        var winh = 200;
    }
    
    var w = window.open(winurl, 'resultwin', 'width=' + winw + ',height=' + winh + ',status=yes,resizable=yes,scrollbars=yes');
    w.focus();
    return w;
}

// typewin can be the id of the element like "frame" (with "#")
function openAjaxQueryIn(typewin, dlgOptions, dlgTitle, url, params) {
	if (typewin == 'window') {
		if (url.indexOf('?') == -1) {
			url += '?';
		} else {
			url += '&';
		}
		url += 'addjsandcss=true';
		if (params) {
			url += '&' + params;
		}
		openResultwin(url);
	} else {
		if (url.indexOf('?') > 0) {
			params += (params ? '&' : '') + url.substr(url.indexOf('?') + 1);
		}
		
		PM.ajaxIndicatorShow(false, false);
		$.ajax({
		    url: url,
		    data: params,
	        type: 'POST',
		    dataType: 'html',
		    success: function(response) {
//				PM.ajaxIndicatorHide();
				var resContainer = '';
				if (typewin == 'dynwin') {
					if (!dlgOptions.width) {
						dlgOptions.width = 450;
					}
					if (!dlgOptions.height) {
						dlgOptions.height = 250;
					}
					if (!dlgOptions.container) {
						dlgOptions.container = 'pmDlgContainer';
					}
					PM.Dlg.createDnRDlg(dlgOptions, dlgTitle, false);
					resContainer = '#' + dlgOptions.container + '_MSG';
				} else {
					if (typewin == 'frame' && $('#infoFrame').length > 0) {
						resContainer = '#infoFrame';
					} else if (typewin[0] == '#' && $(typewin).length > 0) { 
						resContainer = typewin;
					}
				}
				$(resContainer).html(response);
			},
			error: function (XMLHttpRequest, textStatus, errorThrown) {
                if (window.console) console.log(errorThrown);
            },
			complete: function() {
				PM.ajaxIndicatorHide();
			}
		});
	} 
}

/**
 * Convert HEXA color to RGB 
 */
function convertHexToRGB(hexColor){
	var r, g, b;
	if (hexColor == '') {
		r = -1;
		g = -1;
		b = -1;
	} else {
	    r = HexToR(hexColor);
	    g = HexToG(hexColor);
	    b = HexToB(hexColor);
	}
	// Do not change the way to add "," and space because of js compression algorythm...
    var rgb = r.toString() + "," + " " + g.toString() + "," + " " + b.toString();

    return rgb;
}
function HexToR(h) {
	return parseInt((cutHex(h)).substring(0,2),16);
} 
function HexToG(h) {
	return parseInt((cutHex(h)).substring(2,4),16);
} 
function HexToB(h) {
	return parseInt((cutHex(h)).substring(4,6),16);
} 
function cutHex(h) {
	return (h.charAt(0)=="#") ? h.substring(1,7):h;
}  

/**
 * Convert RGB color to HEXA 
 */
function convertRgbToHex(num) {
	var decToHex="";
	var arr = [];
	var numStr = new String();
	numStr = num;

	arr = numStr.split(",");

	for(var i=0;i<3;i++){
		var hexArray = new Array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" );
		var code1 = Math.floor(arr[i] / 16);
		var code2 = arr[i] - code1 * 16;
		decToHex += hexArray[code1];
		decToHex += hexArray[code2];
	}
	return (decToHex);
}	

function generateColor(iClass, nbClass, hexColor1, hexColor2) {
	var r1 = HexToR(hexColor1);
    var g1 = HexToG(hexColor1);
    var b1 = HexToB(hexColor1);
	var r2 = HexToR(hexColor2);
    var g2 = HexToG(hexColor2);
    var b2 = HexToB(hexColor2);
	var nb = (nbClass > 1) ? nbClass - 1 : 1;
	var rOffset = Math.round((r2 - r1)/nb);
	var gOffset = Math.round((g2 - g1)/nb);
	var bOffset = Math.round((b2 - b1)/nb);
	var r = Math.max(Math.min(255, r1 + iClass * rOffset),0);
	var g = Math.max(Math.min(255, g1 + iClass * gOffset),0);
	var b = Math.max(Math.min(255, b1 + iClass * bOffset),0);

	var hexaColor = convertRgbToHex(r + ',' + g + ',' + b);
    
	return hexaColor;
}

/** function used to upper the first letter of a word
 * parameters: word  
 * @return: Word
 */
function upperWord(word) {
    var w = word.charAt(0).toUpperCase() + word.substring(1).toLowerCase();
    return w;
}

/**
 * 
 * get PM.Plugin[............] object
 * return null if error
 * 
 * @param strIn string (with "." separator).
 * 
 * For instance : "drawing" will return PM.Plugin.drawing object
 */
function getPMPluginObjFromString(strIn) {
	var retPluginObj = null;
	
	var retPluginObjTmp = PM.Plugin;
	var pluginNameCltArray = strIn.split(".");
	var ok = false;
	$.each(pluginNameCltArray, function(index, value) {
		var objTmp = retPluginObjTmp[value];
		if (typeof(objTmp) != "undefined") {
			retPluginObjTmp = objTmp;
			ok = true;
		} else {
			ok = false;
		}
		return ok;
	});
	if (ok) {
		retPluginObj = retPluginObjTmp;
	}
	
	return retPluginObj;
}
/******************************************************************************
 *
 * Purpose: Querty Editor plugin
 * Author:  Thomas Raffin, SIRAP
 *
 ******************************************************************************
 *
 * Copyright (c) 2008 SIRAP
 *
 * This is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version. See the COPYING file.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with p.mapper; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ******************************************************************************/


$.extend(PM.Plugin,
{
	google3d:
    {
    	dlgOptions: {width:715, height:550, left:250, top:150, resizeable:true, newsize:true, container:'pmGoogle3DContainer', name:'google3d'},
    	dlgType: 'dynwin',		
    	
    		
    	init: function() {
    		
    	},

    	openDlg: function() {
    		
    		var url = PM_PLUGIN_LOCATION + '/google3d/windowGoogle3d.phtml';
			var params = SID;
			params = params + '&koor=' + PM.maxy_geo + ';' + PM.minx_geo + ';' + PM.xdelta_geo + ';' + PM.ydelta_geo + ';' + $('#scaleinput').val() + '&nalozeno=' + $.nalozenaStran;		
			openAjaxQueryIn(this.dlgType, this.dlgOptions, this.dlgOptions.name, url, params);
		
		}

    }
});
PM.grouplist = {"Katastar":{"groupName":"Katastar","description":"Katastar","layerList":[{"glayerIdx":14,"glayerType":1,"selFields":["PARCELA","IMEKO","SIFKO",null,null,"id_par"],"hyperFields":[["parcela"],[]],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"katastar_odebelitev","glayerOpacity":50,"layerEncoding":"windows-1250"},{"glayerIdx":15,"glayerType":2,"selFields":["PARCELA","IMEKO","SIFKO",null,null,"ID_PAR"],"hyperFields":[["parcela"],[]],"joinList":null,"classes":[],"labelItem":"PARCELA","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"katastar","glayerOpacity":50,"layerEncoding":"windows-1250"},{"glayerIdx":16,"glayerType":4,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":"PARCELA","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"dkn_ime","glayerOpacity":100,"layerEncoding":false},{"glayerIdx":17,"glayerType":4,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":"PARCELA","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"dkn_ime2","glayerOpacity":100,"layerEncoding":false},{"glayerIdx":18,"glayerType":4,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":"PARCELA","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"dkn_ime1","glayerOpacity":100,"layerEncoding":false}],"selHeaders":["Parcela","Ime K.O.","&Scaron;ifra K.O.","Povr&scaron;ina","Knji&#382;na pov.","id_par"],"selStdHeaders":["Parcela","Ime K.O.","&Scaron;ifra K.O.","Povr&scaron;ina","Knji&#382;na pov.","id_par"]},"katastarske_opcine":{"groupName":"katastarske_opcine","description":"Katastarska op&#263;ina","layerList":[{"glayerIdx":6,"glayerType":2,"selFields":["IMEKO","SIFKO"],"hyperFields":[],"joinList":null,"classes":["katastarska op&#263;ina"],"labelItem":"IMEKO","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"katastarske_opcine","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Ime KO","&#353;ifra KO"],"selStdHeaders":["Ime KO","&#353;ifra KO"]},"Stanovnistvo":{"groupName":"Stanovnistvo","description":"Stanovni&#353;tvo","layerList":[{"glayerIdx":20,"glayerType":0,"selFields":["PREZIME","IME","MJESTO_PREBIVALISTA","ULICA","KUCNI_BROJ","GODINA_RODENJA","DATUM_RODENJA","DRZAVA_RODENJA","MJESTO_RODENJA"],"hyperFields":[],"joinList":null,"classes":["Stanovni&#353;tvo"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"Stanovnistvo","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["PREZIME","IME","NASELJE","ULICA","KU&#262;NI_BROJ","GODINA_RO&#393;ENJA","DATUM RO&#393;ENJA","DR&#381;AVA RO&#393;ENJA","MJESTO RO&#393;ENJA"],"selStdHeaders":["PREZIME","IME","NASELJE","ULICA","KU&#262;NI_BROJ","GODINA_RO&#393;ENJA","DATUM RO&#393;ENJA","DR&#381;AVA RO&#393;ENJA","MJESTO RO&#393;ENJA"]},"katastar_zgrada":{"groupName":"katastar_zgrada","description":"Katastar zgrada","layerList":[{"glayerIdx":19,"glayerType":2,"selFields":["ZGRADA","SIF_ZGRADE","sifko"],"hyperFields":[["ZGRADA","SIF_ZGRADE","sifko"],[]],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"katastar_zgrada","glayerOpacity":65,"layerEncoding":"windows-1250"}],"selHeaders":["Zgrada","&#352ifra zgrade","&#352ifra KO"],"selStdHeaders":["Zgrada","&#352ifra zgrade","&#352ifra KO"]},"drzavno_zemljiste":{"groupName":"drzavno_zemljiste","description":"Dr&#382;avno zemlji&scaron;te","layerList":[{"glayerIdx":11,"glayerType":2,"selFields":["PARCELA","IMEKO","NAPOMJENA","RAZPOLAGANJA"],"hyperFields":[],"joinList":null,"classes":["Parcele"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"drzavno_zemljiste","glayerOpacity":35,"layerEncoding":"windows-1250"}],"selHeaders":["Parcela","Ime KO","namjena","razpolaganja"],"selStdHeaders":["Parcela","Ime KO","namjena","razpolaganja"]},"kucni_brojevi":{"groupName":"kucni_brojevi","description":"kucni_brojevi","layerList":[{"glayerIdx":8,"glayerType":0,"selFields":["KB","NASELJE","ULICA"],"hyperFields":[["KB"],[]],"joinList":null,"classes":["Ku&#263;ni brojevi"],"labelItem":"KB","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"kucni_brojevi","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Kb","Naselje","Ulica"],"selStdHeaders":["Kb","Naselje","Ulica"]},"Naselje":{"groupName":"Naselje","description":"Naselje","layerList":[{"glayerIdx":7,"glayerType":2,"selFields":["NASELJE","Maticni_broj_naselja","JMS","IMEKO","SIFKO"],"hyperFields":[],"joinList":null,"classes":["Naselje"],"labelItem":"NASELJE","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"Naselje","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Naselje","Mati&#269;ni broj naselja","JMS","Ime KO","&#353;ifra;ifra KO"],"selStdHeaders":["Naselje","Mati&#269;ni broj naselja","JMS","Ime KO","&#353;ifra;ifra KO"]},"lokalna_samouprava":{"groupName":"lokalna_samouprava","description":"lokalna samouprava","layerList":[{"glayerIdx":9,"glayerType":2,"selFields":["OPCINA_GRAD",null,"SIFRA"],"hyperFields":[],"joinList":null,"classes":["lokalna samouprava"],"labelItem":"OPCINA_GRAD","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"opcina_grad","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":10,"glayerType":1,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"granice_ZUP_GRADA","glayerOpacity":100,"layerEncoding":false}],"selHeaders":["Opcina_grad","&#382;upanija","sifra"],"selStdHeaders":["Opcina_grad","&#382;upanija","sifra"]},"VODOVOD":{"groupName":"VODOVOD","description":"vodovod","layerList":[{"glayerIdx":21,"glayerType":1,"selFields":["cijev","fi","opis"],"hyperFields":[],"joinList":null,"classes":["vodovod - cijevi"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"vodovod_cjevi","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":22,"glayerType":0,"selFields":["element","opis"],"hyperFields":[],"joinList":null,"classes":["hidranti"],"labelItem":"element","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"hidranti","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["cijev","fi","opis"],"selStdHeaders":["cijev","fi","opis"]},"KANALIZACIJA":{"groupName":"KANALIZACIJA","description":"kanalizacija_cjevi","layerList":[{"glayerIdx":23,"glayerType":1,"selFields":["cijev","opis"],"hyperFields":[],"joinList":null,"classes":["kanalizacija - cjevi"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"kanalizacija_cjevi","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":24,"glayerType":0,"selFields":["element","opis"],"hyperFields":[],"joinList":null,"classes":["&#353;ahti"],"labelItem":"element","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"kanalizacija_sahti","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["test1","test2"],"selStdHeaders":["test1","test2"]},"elektro_UPU":{"groupName":"elektro_UPU","description":"Elektroenergetsk mre&#382;a","layerList":[{"glayerIdx":25,"glayerType":1,"selFields":["OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Elektroenergetika - linije"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"elektro_linije","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":30,"glayerType":0,"selFields":["OZNAKA","NAMJENA","PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Elektroenergetika - to&#269;ke"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"elektro_tocke","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"],"selStdHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"]},"telekom_UPU":{"groupName":"telekom_UPU","description":"Telekomunikacijska mre&#382;a","layerList":[{"glayerIdx":26,"glayerType":1,"selFields":["OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Telekomunikacije - linije"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"telekom_linije","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":27,"glayerType":0,"selFields":["OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Telekomunikacije - to&#269;ke"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"infra_tocke","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"],"selStdHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"]},"plinovod_UPU":{"groupName":"plinovod_UPU","description":"Plinovodna mre&#382;a","layerList":[{"glayerIdx":28,"glayerType":1,"selFields":["OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Plinovod"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"plinovod_linije","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":29,"glayerType":1,"selFields":["OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Naftovod"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"naftovod_linije","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"],"selStdHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"]},"promet_UPU":{"groupName":"promet_UPU","description":"Promet","layerList":[{"glayerIdx":31,"glayerType":2,"selFields":["OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Promet"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"promet_ploskev","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":32,"glayerType":0,"selFields":["OZNAKA","NAMJENA","PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Promet elementi"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"promet_tocke","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"],"selStdHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"]},"Voda_UPU":{"groupName":"Voda_UPU","description":"Voda_UPU","layerList":[{"glayerIdx":38,"glayerType":1,"selFields":["OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["voda linije"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"voda_linije","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":39,"glayerType":0,"selFields":["OZNAKA","NAMJENA","PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["voda elementi"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"voda_tocke","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"],"selStdHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"]},"graditelska_bastina_UPU":{"groupName":"graditelska_bastina_UPU","description":"Graditeljska ba&scaron;tina","layerList":[{"glayerIdx":35,"glayerType":2,"selFields":["NAMJENA","POVRSINA_M2","PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Graditeljska ba&scaron;tina"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"Graditelska_bastina","glayerOpacity":50,"layerEncoding":"windows-1250"},{"glayerIdx":36,"glayerType":1,"selFields":[],"hyperFields":[],"joinList":null,"classes":["granica graditeljske ba&scaron;tine"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"PGC-ojacana-debelina-poligona","glayerOpacity":100,"layerEncoding":false},{"glayerIdx":37,"glayerType":0,"selFields":["ID","OZNAKA","NAMJENA","PROSTORNI_PLAN","X","Y"],"hyperFields":[],"joinList":null,"classes":["elementi graditeljska ba&scaron;tine"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"graditeljska_bastina_tocke","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["Namjena","Povr&scaron;ina(m2)","Prostorni plan"],"selStdHeaders":["Namjena","Povr&scaron;ina(m2)","Prostorni plan"]},"Namjena_UPU":{"groupName":"Namjena_UPU","description":"Namjena UPU","layerList":[{"glayerIdx":34,"glayerType":2,"selFields":["OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"Namjena_UPU","glayerOpacity":80,"layerEncoding":"windows-1250"}],"selHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"],"selStdHeaders":["Oznaka","Namjena","Du&#382;ina(m)","Prostorni plan"]},"Granica_UPU":{"groupName":"Granica_UPU","description":"Granica UPU","layerList":[{"glayerIdx":33,"glayerType":2,"selFields":["ID","OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"hyperFields":[],"joinList":null,"classes":["Granica UPU"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"Granica_UPU","glayerOpacity":70,"layerEncoding":false}],"selHeaders":["ID","OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"],"selStdHeaders":["ID","OZNAKA","NAMJENA",null,"PROSTORNI_PLAN"]},"DOF2000":{"groupName":"DOF2000","description":"DOF2000","layerList":[{"glayerIdx":2,"glayerType":3,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"DOF2000","glayerOpacity":100,"layerEncoding":false}],"selHeaders":[],"selStdHeaders":[]},"DOF5000_10":{"groupName":"DOF5000_10","description":"DOF5000_10","layerList":[{"glayerIdx":1,"glayerType":3,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"DOF5000_10","glayerOpacity":100,"layerEncoding":false}],"selHeaders":[],"selStdHeaders":[]},"HOK5000":{"groupName":"HOK5000","description":"HOK5000","layerList":[{"glayerIdx":4,"glayerType":3,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"HOK5000","glayerOpacity":30,"layerEncoding":false}],"selHeaders":[],"selStdHeaders":[]},"TK_25":{"groupName":"TK_25","description":"TK_25","layerList":[{"glayerIdx":3,"glayerType":3,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"TK_25","glayerOpacity":100,"layerEncoding":false}],"selHeaders":[],"selStdHeaders":[]},"NR2011":{"groupName":"NR2011","description":"Namjena povr&#353;ina","layerList":[{"glayerIdx":5,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"Namjena 2011","glayerOpacity":60,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"Ceste":{"groupName":"Ceste","description":"Ceste","layerList":[{"glayerIdx":12,"glayerType":1,"selFields":["ID","ULICA"],"hyperFields":[],"joinList":null,"classes":["Ceste"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"Ceste","glayerOpacity":80,"layerEncoding":"windows-1250"},{"glayerIdx":13,"glayerType":4,"selFields":[],"hyperFields":[],"joinList":null,"classes":[],"labelItem":"ULICA","isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"Ceste_ime","glayerOpacity":100,"layerEncoding":false}],"selHeaders":["ID","ULICA"],"selStdHeaders":["ID","ULICA"]},"cestovni_promet_NR":{"groupName":"cestovni_promet_NR","description":"Cestovni promet - planirano","layerList":[{"glayerIdx":40,"glayerType":1,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","STANJE"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"cestovni_promet_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":41,"glayerType":1,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","STANJE"],"hyperFields":[],"joinList":null,"classes":["postoje&#269;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"cestovni_promet_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"zeleznicki_promet":{"groupName":"zeleznicki_promet","description":"&#381;eljezni&#269;ki promet - planirano","layerList":[{"glayerIdx":42,"glayerType":1,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","STANJE"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"zeleznicki_promet_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":43,"glayerType":1,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","STANJE"],"hyperFields":[],"joinList":null,"classes":["postoje&#269;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"zeleznicki_promet_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"zracni_promet":{"groupName":"zracni_promet","description":"&#381;eljezni&#269;ki promet - postoje&#269;e","layerList":[{"glayerIdx":44,"glayerType":0,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","STANJE"],"hyperFields":[],"joinList":null,"classes":["helidrom"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"zracni_promet","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"dalekovod":{"groupName":"dalekovod","description":"Dalekovod - planirano","layerList":[{"glayerIdx":45,"glayerType":1,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","Stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"dalekovod_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":46,"glayerType":1,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","Stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#269;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"dalekovod_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"telekomunikacije":{"groupName":"telekomunikacije","description":"Elektroni&#269;ke komunikacije","layerList":[{"glayerIdx":47,"glayerType":1,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["Kanali i vodovi"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"vodovi_i_kanali","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":48,"glayerType":0,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","Stanje"],"hyperFields":[],"joinList":null,"classes":["Blokovi"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"blokovi","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"PLINOVOD":{"groupName":"PLINOVOD","description":"Plinovod - planirano","layerList":[{"glayerIdx":49,"glayerType":1,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"plinovod_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":50,"glayerType":1,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#263;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"plinovod_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"NAFTOVOD":{"groupName":"NAFTOVOD","description":"Naftovod - planirano","layerList":[{"glayerIdx":51,"glayerType":1,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"naftovod_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":52,"glayerType":1,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#263;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"naftovod_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"mineralne":{"groupName":"mineralne","description":"Mineralne surovine","layerList":[{"glayerIdx":53,"glayerType":2,"selFields":["OPIS","OPIS1","OPIS2","\u0160IFRA","STANJE"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"mineralne","glayerOpacity":70,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"krajobraz":{"groupName":"krajobraz","description":"Krajobraz","layerList":[{"glayerIdx":61,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"krajobraz","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"ekoloska_mreza":{"groupName":"ekoloska_mreza","description":"Ekoloska mreza - divlje svojte","layerList":[{"glayerIdx":62,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["Divlje svojte"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"ekoloska_mreza_divlje","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":63,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["Ptice"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"ekoloska_mreza_ptice","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"povijesna_graditeljska_cjelina":{"groupName":"povijesna_graditeljska_cjelina","description":"Naselja i dijelova naselja","layerList":[{"glayerIdx":64,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"povijesna_graditeljska_cjelina","glayerOpacity":60,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"podrucja":{"groupName":"podrucja","description":"Podru&#269;ja i djelovi primjene planskih mjera za&scaron;tite","layerList":[{"glayerIdx":65,"glayerType":1,"selFields":["OPIS","OPIS1","OPIS2",null,"STANJE"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"podrucja","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"zastiteni_djelovi":{"groupName":"zastiteni_djelovi","description":"Za&scaron;ti&#263;eni dijelovi prirode","layerList":[{"glayerIdx":66,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"zastiteni_djelovi_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":67,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#263;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"zastiteni_djelovi_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":68,"glayerType":0,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"zastiteni_djelovi_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"minsko_polje":{"groupName":"minsko_polje","description":"Minsko polje","layerList":[{"glayerIdx":69,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"minsko_polje","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"poplavno_podrucje":{"groupName":"poplavno_podrucje","description":"Poplavno podru&#269;je","layerList":[{"glayerIdx":70,"glayerType":2,"selFields":["OPIS","OPIS1","OPIS2",null,"STANJE"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"poplavno_podrucje","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"hidromelioracija":{"groupName":"hidromelioracija","description":"Hidromelioracija","layerList":[{"glayerIdx":71,"glayerType":2,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"hidromelioracija","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"arheoloska_bastina":{"groupName":"arheoloska_bastina","description":"Arheolo&scaron;ka ba&scaron;tina - planirano","layerList":[{"glayerIdx":72,"glayerType":0,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"arheoloska_bastina_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":73,"glayerType":0,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#263;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"arheoloska_bastina_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"sakralne_gradevine":{"groupName":"sakralne_gradevine","description":"Sakralne gra\u00f0evine","layerList":[{"glayerIdx":74,"glayerType":0,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"sakralne_gradevine","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"memorijalna_bastina":{"groupName":"memorijalna_bastina","description":"Memorijalna ba&scaron;tina - planirano","layerList":[{"glayerIdx":75,"glayerType":0,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"memorijalna_bastina_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":76,"glayerType":0,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#263;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"memorijalna_bastina_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"civilne_gradevine":{"groupName":"civilne_gradevine","description":"Civilne gra&#273;evine - postoje&#263;e","layerList":[{"glayerIdx":77,"glayerType":0,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#263;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"civilne_gradevine_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":78,"glayerType":0,"selFields":["opis","opis1","opis2",null,"stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"civilne_gradevine_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"vodooskrba":{"groupName":"vodooskrba","description":"Vodoopskrba - planirano","layerList":[{"glayerIdx":54,"glayerType":1,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"vodooskrba_cevovod_plan","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":55,"glayerType":0,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#263;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"vodooskrba_cevovod_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"otpadne":{"groupName":"otpadne","description":"Odvodnaj otpadnih voda - planirano","layerList":[{"glayerIdx":56,"glayerType":1,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["planirano"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"otpadne_vode_planirano","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":57,"glayerType":0,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"otpadne_vode_planirano1","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":58,"glayerType":0,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["postoje&#263;e"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"otpadne_vode_postojece","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]},"odvodnja":{"groupName":"odvodnja","description":"Naftovod - planirano","layerList":[{"glayerIdx":59,"glayerType":1,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":["melioracijska odvodnja"],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"kanalska_mreza","glayerOpacity":100,"layerEncoding":"windows-1250"},{"glayerIdx":60,"glayerType":0,"selFields":["opis","opis1","opis2","\u0160ifra","stanje"],"hyperFields":[],"joinList":null,"classes":[],"labelItem":null,"isXYLayer":false,"XYLayerProperties":null,"skipLegend":false,"glayerName":"regulacijski_zastitni","glayerOpacity":100,"layerEncoding":"windows-1250"}],"selHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"],"selStdHeaders":["OPIS","OPIS1","OPIS2","&Scaron;IFRA","STANJE"]}};
