/* --------------------------------------------------------------
 * OTHER JAVASCRIPT FUNCTIONS FOR BDGA
 * -------------------------------------------------------------- */

var oZoomMxExtCtrl, oZoomMxExtOpt, oZoomBoxInCtrl, oZoomBoxInOpt,
    oZoomBoxOutCtrl, oZoomBoxOutOpt, oDragPanCtrl, oDragPanOpt,
    //oDrawPtCtrl, oDrawPtOpt, oDrawPlCtrl, oDrawPlOpt,
    oDrawLnCtrl, oDrawLnOpt, oNavCtrl, oPrevButton, oNextButton,
    oModifyLnCtrl, oModifyLnOpt, oDeleteLnCtrl, oDeleteLnCtrl,
    oDragPanButton, oDrawLnButton, oModifyLnButton, oDeleteLnButton;

function addSeparator(oToolbar){
    oToolbar.add(new Ext.Toolbar.Spacer());
    oToolbar.add(new Ext.Toolbar.Separator());
    oToolbar.add(new Ext.Toolbar.Spacer());
} 

function initToolbarContent() {
    // ZoomToMaxExtent control
    oZoomMxExtCtrl = new OpenLayers.Control.ZoomToMaxExtent({
        map: oMap, title: 'Zoom to maximum map extent'
    });
    oZoomMxExtOpt = { iconCls: 'zoomfull', toggleGroup: 'map' };
    oToolbar.addControl( oZoomMxExtCtrl, oZoomMxExtOpt );
    addSeparator(oToolbar);

    // ZoomBox In control
    oZoomBoxInCtrl = new OpenLayers.Control.ZoomBox({
          title: 'Zoom in: click in the map or use the left '
                +'mouse button and drag to create a rectangle'
    });
    oZoomBoxInOpt = { iconCls: 'zoomin', toggleGroup: 'map' };
    oToolbar.addControl( oZoomBoxInCtrl, oZoomBoxInOpt );

    // ZoomBox Out control
    oZoomBoxOutCtrl = new OpenLayers.Control.ZoomBox({ out: true,
          title: 'Zoom out: click in the map or use the left '
                +'mouse button and drag to create a rectangle'
    });
    oZoomBoxOutOpt = { iconCls: 'zoomout', toggleGroup: 'map' };
    oToolbar.addControl( oZoomBoxOutCtrl, oZoomBoxOutOpt);

    // DragPan control
    oDragPanCtrl = new OpenLayers.Control.DragPan({ isDefault: true,
          title: 'Pan map: keep the left mouse button pressed and drag the map'
    });
    oDragPanOpt = { iconCls: 'pan', toggleGroup: 'map' };
    oToolbar.addControl( oDragPanCtrl, oDragPanOpt );
    oDragPanButton = oToolbar.getButtonForControl(oDragPanCtrl);

    addSeparator(oToolbar);

    //DrawFeature Point control
    /*
    oDrawPtCtrl = new OpenLayers.Control.DrawFeature(
        olWFSPoint, OpenLayers.Handler.Point,{title: 'Draw a point on the map'}
    );
    oDrawPtOpt = { iconCls: 'drawpoint', toggleGroup: 'map' };
    oToolbar.addControl( oDrawPtCtrl, oDrawPtOpt );
    */

    //DrawFeature Line control
    oDrawLnCtrl = new OpenLayers.Control.DrawFeature(
        olWFSRoads, OpenLayers.Handler.Path,
        { title: 'Draw a new road on the map' }
    );
    oDrawLnOpt = { iconCls: 'drawline', toggleGroup: 'map'};
    oToolbar.addControl( oDrawLnCtrl, oDrawLnOpt );
    oDrawLnCtrl.events.register("featureadded",'' , roadFeatureAdded);
    oDrawLnButton = oToolbar.getButtonForControl(oDrawLnCtrl);

    //DrawFeature Polygon control
    /*
    oDrawPlCtrl = new OpenLayers.Control.DrawFeature(
        olWFSPolygon, OpenLayers.Handler.Polygon,
        { title: 'Draw a polygon on the map' }
    );
    oDrawPlOpt = { iconCls: 'drawpolygon', toggleGroup: 'map' };
    oToolbar.addControl(oDrawPlCtrl,oDrawPlOpt);
    */

    // DeleteFeatures control for roads
    oDeleteLnCtrl = new OpenLayers.Control.DeleteFeature(
        olWFSRoads, { 'box': true,
                title: "Delete one or more roads on the map"});
    oDeleteLnOpt = { iconCls: 'deletefeature', toggleGroup: 'map'};
    oToolbar.addControl(oDeleteLnCtrl, oDeleteLnOpt);
    oDeleteLnButton = oToolbar.getButtonForControl(oDeleteLnCtrl);
    oDeleteLnCtrl.events.register("activate", '', onDeleteLnCtrlActivated);
    oDeleteLnCtrl.events.register("deactivate", '', onDeleteLnCtrlDeactivated);
    oDeleteLnCtrl.events.register("beforefeaturesdeleted", '', 
                                  beforeRoadsDeleted);
    oDeleteLnCtrl.events.register("deletefeatures", '', deleteRoads);

    // ModifyFeature control for roads
    oModifyLnCtrl = new OpenLayers.Control.ModifyFeature(
        olWFSRoads, { title: 'Edit a road on the map'});
    oModifyLnOpt = { iconCls: 'modifyfeature', toggleGroup: 'map'};
    oToolbar.addControl( oModifyLnCtrl, oModifyLnOpt );
    oModifyLnButton = oToolbar.getButtonForControl(oModifyLnCtrl);
    oModifyLnCtrl.events.register("activate", '', onModifyLnCtrlActivated);
    oModifyLnCtrl.events.register("deactivate", '', onModifyLnCtrlDeactivated);

    addSeparator(oToolbar);

    //Navigation History
    oNavCtrl= new OpenLayers.Control.NavigationHistory();
    oMap.addControl(oNavCtrl);
    oNavCtrl.activate();

    //Navigation History Back
    oPrevButton =  new Ext.Toolbar.Button({
          iconCls: 'back', tooltip: 'Quick navigation : previous',
          handler: oNavCtrl.previous.trigger
    });
    oToolbar.add( oPrevButton );

    //Navigation History Next
    oNextButton = new Ext.Toolbar.Button({
          iconCls: 'next', tooltip: 'Quick navigation : next',
          handler: oNavCtrl.next.trigger
    });
    oToolbar.add( oNextButton );
    addSeparator(oToolbar);
            
    oToolbar.activate();

 /* --------------------------------------------------------------
 *  EVENTS REGISTRATIONS/TRIGGER AFTER THE TOOLBAR HAS BEEN LOADED
 * -------------------------------------------------------------- */   
    oMap.events.register("moveend", oMap, toggleEditTools);
    toggleEditTools();
}


/**
 * Method: sortByCityName
 * Sorts cities by their name
 *
 * Parameters:
 * a -
 * b -
 *
 * Returns:
 * {Array} sorted by city name
 */
function sortByCityName(a, b) {
    var x = a.cityName.toLowerCase();
    var y = b.cityName.toLowerCase();
    return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}

/**
 * Method: setCities
 * Dinamically create a list of cities with their coordinates, ordered by 
 * their names.  When a city is selected, the map moves to its location.
 *
 * Parameters:
 * response - DescribeFeatureType response
 */
function setCities(response) {
    var oText = new OpenLayers.Format.Text();
    var oFeatures = oText.read(response.responseText);
    var aCities = new Array();
    var aCitiesN = new Array();
    var nFeatures, nCities, oCityComboBox, oSelect, oCityStore;

    // put the results in an array first to be able to sort it
    nFeatures = oFeatures.length;
    for (var i=0; i<nFeatures; i++){
        var szValue = "";
        szValue += oFeatures[i].geometry.x;
        szValue += ",";
        szValue += oFeatures[i].geometry.y

        aCities[i] = {
          lonlat: szValue,
          cityName: oFeatures[i].attributes['title']
        };
    }

    // sort the array by city name
    aCities.sort(sortByCityName);

    // create an extra array containing arrays instead of objects
    // because Ext.form.ComboBox can use theses type of arrays as
    // store value.
    nCities = aCities.length;
    for (var i=0; i<nCities; i++){
        var aLonLatCity = new Array();
        var oLonLat = new OpenLayers.LonLat.fromString(aCities[i]['lonlat']);
        aLonLatCity.push(oLonLat);
        aLonLatCity.push(aCities[i]['cityName']);
        aCitiesN.push(aLonLatCity);
    }

    // create on option per city and add it to the select element
    oSelect=document.getElementById("zoomToCity");
    
    if (oSelect){
        for (i=0; i<aCities.length; i++){
            var oOption = document.createElement('option');
            oOption.text=aCities[i]['cityName'];
            oOption.value=aCities[i]['lonlat'];
            try
            {
                oSelect.add(oOption,null); // standards compliant
            }     
            catch(ex)
            {
                oSelect.add(oOption); // IE only
            }
        }
        // Enable the list and remove the "wait" message
        oSelect.disabled = "";
        oSelect.remove(0);
    } else { // use a Ext combobox instead
        oCityStore = new Ext.data.SimpleStore({
            fields: ['location', 'text'],
            data : aCitiesN
        });
    
        oCityComboBox = new mapfish.widgets.Shortcuts({
            map: oMap,
            el: 'gotocity',
            store: oCityStore,
            listWidth: 167,
            width: 150,
            templates: {
                header: new Ext.Template("Choose a city in the list"),
                footer: new Ext.Template("The map will automatically center to this location")
            }
        });
        oCityComboBox.render();
    }
}

/**
 * Method: zoomToCity
 * This function is called when an city is selected and will move the map
 * to its location using map.setCenter function.
 *
 * forceZoomChange is set to true to change the renderer left and top
 * each time we use this function.
 *
 * Parameters:
 * element - html option element of a select representing the city which has
 *           lon,lat as value.
 */
function zoomToCity(element){
    if(!element){
        var oExtComboBox = Ext.get('zoomToCityExt');
        element = oExtComboBox.getValue();
        //alert(this);
    }
    oMap.setCenter(
        new OpenLayers.LonLat.fromString(element.value), // lonlat
        oMap.getZoom(),                                  // zoom
        '',                                              // dragging
        true                                             // forceZoomChange
    );
}

function showMsg( szTitle, szMsg ){
    Ext.example.msg(szTitle, szMsg, 'yes');
};

/**
 * Method: popMap
 * Pop current map view in new window.  For MapServer layers only.
 */
function popMap() {
/*
    var szURL = oMap.getMapURL();

    var win = new Ext.Window({
          title    : 'Current view of the map',
          closable : true,
          width    : 600,
          height   : 350,
          border : false,
          plain    : true,
          region: 'center',
          items: [{
              html: "<img src="+szURL+">",
              border: false
          }]
    });

    //win.show(button);
    win.show();
*/
    window.open(
        oMap.getMapURL(),
        '_blank',
        'fullscreen=no'            
    );
}

/**
 * Method: getMapURL
 * Return a query string for the map with current visible layers
 *
 * Parameters:
 *
 * Returns:
 * {String} A string with the basic layer's url and map parameters 
 *          and also the passed-in bounds and appropriate tile size 
 *          specified as parameters and the current visible overlays.
 */
OpenLayers.Map.prototype.getMapURL = function () {
    var url = "";
    for (var i=0, len=this.layers.length; i<len; i++) {
        if (!this.layers[i].isVector && this.layers[i].params != null) {
            if (this.layers[i].isBaseLayer && this.layers[i].getVisibility()) {
                url += this.getBasicLayerURL(this.getExtent(), i);
            } else if(this.layers[i].inRange && this.layers[i].getVisibility()){
                url += "&layers=" + this.layers[i].params.layers;
            }
        }
    }
    url = url.replace(" ", "%20");

    return url;
}

/**
 * Method: getBasicLayerURL
 * Return a query string for the map's basic layer
 *
 * Parameters:
 * bounds - {<OpenLayers.Bounds>} A bounds representing the bbox 
 *                                for the request
 * nLayer - integer               The position of the current basic
 *                                layer in the layer array
 *
 * Returns:
 * {String} A string with the basic layer's url and map parameters 
 *          and also the passed-in bounds and appropriate tile size 
 *          specified as parameters.
 */
OpenLayers.Map.prototype.getBasicLayerURL = function (bounds, nBasicLayer) {
    bounds = this.layers[nBasicLayer].adjustBounds(bounds);
    // Make a list, so that getFullRequestString uses literal "," 
    var extent = [bounds.left, bounds. bottom, bounds.right, bounds.top];

    var imageSize = this.getSize(); 
        
    // make lists, so that literal ','s are used 
    var url = this.layers[nBasicLayer].getFullRequestString(
                 {mapext:   extent,
                  imgext:   extent,
                  map_size: [imageSize.w, imageSize.h],
                  imgx:     imageSize.w / 2,
                  imgy:     imageSize.h / 2,
                  imgxy:    [imageSize.w, imageSize.h]
                  });
        
    return url;
}

