//$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/apps/igeoportal-standard/branches/2.5_testing/scaleswitcher.js $
/*----------------------------------------------------------------------------
 This file is part of deegree, http://deegree.org/
 Copyright (C) 2001-2009 by:
 - Department of Geography, University of Bonn -
 and
 - lat/lon GmbH -

 This library 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 library 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 library; if not, write to the Free Software Foundation, Inc.,
 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

 Contact information:

 lat/lon GmbH
 Aennchenstr. 19, 53177 Bonn
 Germany
 http://lat-lon.de/

 Department of Geography, University of Bonn
 Prof. Dr. Klaus Greve
 Postfach 1147, 53001 Bonn
 Germany
 http://www.geographie.uni-bonn.de/deegree/

 e-mail: info@deegree.org
----------------------------------------------------------------------------*/

function ScaleSwitcher(label, listOfScales) {

    // variable declaration
    this.label = label;
    this.listOfScales = listOfScales;
    //this.bgcolor = bgcolor; //JM: refactored (css)
    this.proxy = null;
    this.scale = null;
    this.targetDoc = null;
    this.parentElem = null;
    this.internalActionPerformed = false;

    // method declaration
    this.paint = paint;
    this.repaint = repaint;
    this.createList = createList;
    this.switchScale = switchScale;
    this.updateMap = updateMap;
    this.getActualScaleValue = getActualScaleValue;
    this.removeElements= removeElements;
    this.setProxy = setProxy;
    this.getProxy = getProxy ;
    this.setScale = setScale;
    this.getScale = getScale;
    this.paintNow = paintNow;
    this.sendRPC = sendRPC;
    this.createRPC = createRPC;
    this.zoomToFullExtent = zoomToFullExtent;

    /**
    * From the igeoportal documentation
    * Method to paint the ScaleSwitcher HTML part to the portal
    */
    function paint(targetDocument, parentElement) {
        this.targetDoc = targetDocument;
        //this.targetDoc.getElementsByTagName( "body" )[0].bgcolor = this.bgcolor; //JM: refactored (css)
        this.parentElem = parentElement;
        var temporaryScale = this.getScale();
        
        if( temporaryScale != null && temporaryScale != 0 || temporaryScale == -1 ){
            removeNodeById( targetDocument, "spanScaleSwitchElement" );
            removeNodeById( targetDocument, "scaleList" );
            
            var span = targetDocument.createElement( "span" );
            span.setAttribute( "class", "listfont" );
            span.setAttribute( "id", "spanScaleSwitchElement" );
            var b = targetDocument.createElement( "b" );
            var font = targetDocument.createElement( "font" );
            //If condition added to enable loading images
            if ( label.length > 0 ) {
            	/* this is deegree standard procedure */
	            var ltxt = targetDocument.createTextNode( label + " " );
    	        font.appendChild( ltxt );
            } else {
                /* Enables loading image instead of text */
            	var img = targetDocument.createElement( "img" );
            	img.setAttribute( "src", "./images/label_scale.gif" );
            	font.appendChild( img );
            }
            b.appendChild( font );
            span.appendChild( b );
            parentElement.appendChild( span );
            
            var select = this.createList( targetDocument );
            parentElement.appendChild( select );
        }
    }

    /**
    * From the igeoportal documentation
    * Method called each time an action as been performed to update this module
    */
    function repaint() {
        //this.targetDoc.getElementsByTagName( "body" )[0].bgcolor = this.bgcolor; //JM: refactored (css)
        
        if ( !this.internalActionPerformed ) {
            if (this.removeElements()) {
                this.getActualScaleValue();
            }
        } else {
            this.internalActionPerformed = false;
            if (this.removeElements()) {
                this.paintNow();
            }
        }
    }

    /**
    * Help method to display the correct scale value
    */
    function paintNow() {
        this.paint(this.targetDoc, this.parentElem );
    }

    /**
    * Method to create the HTML combobox of the ScaleSwitcher Module dynamically
    */
    function createList( targetDocument ) {
        var sel = targetDocument.createElement("select");
        sel.style.width = "120px"
        sel.style.background = "#FFFFEE";
        sel.name = "scales";
        sel.id = "scaleList";        
        sel.size = 1;
        sel['onchange'] = new Function ( "parent.controller.vScaleSwitcher.switchScale(this);" );
        
        var list = listOfScales.split(";");
        var temporaryScale = this.getScale();
        
        for ( var i = 0; i < list.length; i++ ){
            var tokens = list[i].split('|');
            var tokenScale = tokens[0]; // "1:25000"
            var tokenLabel = tokens[0]; // default: label equals scale
            if ( tokens.length == 2 ) {
                // label is set in configuration:
                tokenLabel = tokens[1]; // "someLabel"
            }
            if ( i == 0 ) {
                var opt = targetDocument.createElement( "option" );
                opt.setAttribute("style", "color:#FFFFEE");
                var tmpLabel = "1:" + temporaryScale;
                if ( temporaryScale == -1 ) {
                    opt.setAttribute( "value", 'select scale' );
                    var txt = targetDocument.createTextNode( 'select scale' );
                } else {
                    for ( var j = 0; j < list.length; j++ ){
                        var myTokens = list[j].split('|');
                        //myTokens[0] = 1:25000 (mandatory)
                        //myTokens[1] = someLabel (optional)
                        if ( myTokens.length == 2 && myTokens[0].split( ':' )[1] == this.getScale() ) {
                            tmpLabel = myTokens[1];
                        }
                    }
                    opt.setAttribute( "value", '1:'+temporaryScale );
                    //var txt = targetDocument.createTextNode( '1:'+temporaryScale );
                    var txt = targetDocument.createTextNode( tmpLabel );
                }
                opt.appendChild( txt );
                sel.appendChild( opt );
            }
            //if ( ('1:'+temporaryScale) != list[i] ) {
            if ( ('1:'+temporaryScale) != tokenScale  ) {
                var opt = targetDocument.createElement( "option" );
                //opt.setAttribute( "value", list[i] );
                opt.setAttribute( "value", tokenScale );
                //var txt = targetDocument.createTextNode( list[i] );
                var txt = targetDocument.createTextNode( tokenLabel );
                opt.appendChild( txt );
                sel.appendChild( opt );
            }
        }
        return sel;
    }

    /**
    * This method gets the new BBOX corresponding to the selected scale value
    */
    function switchScale( select ) {
        var task = "getNewBBOX";
        var scaleValue = select.value;
        if ( scaleValue != 'select scale' ) {
            this.internalActionPerformed = true;
            var rpc = createRPC(task, scaleValue);
            sendRPC(rpc, this.proxy);
        }
    }

    /**
    * This method gets the current scale value
    * when an action has been perform outside of this module
    */
    function getActualScaleValue() {
        var task = "getActualScaleValue";
        var rpc = createRPC(task);
        sendRPC(rpc, this.proxy);
    }

    /**
    * update the MapView with help of the bbox specified by (minx, miny, maxx, maxy)
    */
    function updateMap(minx, miny, maxx, maxy ) {
        var env = new Envelope( minx, miny, maxx, maxy );
        var event = new Event( 'ScaleSwitcher', 'BBOX', env );
        parent.controller.actionPerformed( event );
    }

    /**
    * removes the HTML element
    */
    function removeElements() {
        var removed = false;
        var node = this.targetDoc.getElementById("scaleList");

        if( node != null ){
            var pn = node.parentNode;
            pn.removeChild( node );
            removed = true;
        }

        var node2 = this.targetDoc.getElementById("spanScaleSwitchElement");

        if( node2 != null ){
            var pn2 = node2.parentNode;
            pn2.removeChild( node2 );
            removed = removed && true;
        }
        return removed;
    }

    /**
    * sets the proxy
    */
    function setProxy(vproxy){
        this.proxy = vproxy;
    }

    /**
    * sets the scale
    */
    function setScale(vscale){
        this.scale = vscale;
    }

    /**
    * returns the proxy
    */
    function getProxy(){
        return this.proxy;
    }

    /**
    * returns the scale
    */
    function getScale(){
        return this.scale;
    }

    /**
    * Method to create an RPC request
    */
    function createRPC(task, vscaleValue) {
        var b = parent.controller.mapModel.getBoundingBox();
        var width = parent.controller.mapModel.getWidth();
        var height = parent.controller.mapModel.getHeight();
        var coordsys = parent.controller.mapModel.getSrs();

        var rpc = "<?xml version='1.0' encoding='UTF-8'?><methodCall>" +
                  "<methodName>mapView:changeScale</methodName><params><param><value><struct>"+
                  "<member><name>minx</name><value><double>"+ b.minx +"</double></value></member>" +
                  "<member><name>miny</name><value><double>"+ b.miny +"</double></value></member>" +
                  "<member><name>maxx</name><value><double>"+ b.maxx +"</double></value></member>" +
                  "<member><name>maxy</name><value><double>"+ b.maxy +"</double></value></member>"+
                  "<member><name>mapWidth</name><value><double>"+width+"</double></value></member>"+
                  "<member><name>mapHeight</name><value><double>"+height+"</double></value></member>"+
                  "<member><name>crs</name><value><string>"+coordsys+"</string></value></member>"+
                  "<member><name>taskFromJSObject</name><value><string>"+task+"</string></value></member>";

        if ("getNewBBOX" == task) {
            var savedScaleValue = parent.controller.vScaleSwitcher.getScale();
            rpc += "<member><name>requestedScale</name><value><string>"+vscaleValue+"</string></value></member>"+
                   "<member><name>savedScaleValue</name><value><double>"+savedScaleValue+"</double></value></member>";
        }

        return rpc + "</struct></value></param></params></methodCall>";
    }

    /**
    * submits an RPC request
    */
    function sendRPC(vrpc, vproxy) {
        vproxy.forms[0].method = "post";
        vproxy.forms[0].action = "control?rpc=" + encodeURIComponent(vrpc);
        vproxy.forms[0].submit();
    }

    /**
    * zoomToFullExtent() of MapController is called
    */
    function zoomToFullExtent() {
        this.internalActionPerformed = false;
        parent.controller.vMapController.zoomToFullExtent();
        parent.controller.repaint();
    }
}