// init the tbar_items object first
var tbar_items = {};
var toolbar;        // global toolbar var
var viewport;       // global layout var
var qResultWin;     //Window containing point query results
var activeLayerWin = new Ext.Window({}); //Window containing queryable layers 
var activeLayer;    // id of the current active layer

// Add controls to the list of toolbar controls
tbar_items.zoombox  = new OpenLayers.Control.ZoomBox();
tbar_items.boxQuery = new OpenLayers.Control();
tbar_items.pointQuery = new OpenLayers.Control();

// defines a style map for measuring tool (make the lines look cool)
sketchSymbolizers = {
    "Point": {
        pointRadius: 4,
        graphicName: "square",
        fillColor: "white",
        fillOpacity: 1,
        strokeWidth: 1,
        strokeOpacity: 1,
        strokeColor: "#333333"
    },
    "Line": {
        strokeWidth: 3,
        strokeOpacity: 1,
        strokeColor: "#000000", //666666",
        strokeDashstyle: "dash"
    } 
};

// measure styles (make the lines pretty)
var style = new OpenLayers.Style();
style.addRules([
    new OpenLayers.Rule({symbolizer: this.sketchSymbolizers})
]);
var styleMap = new OpenLayers.StyleMap({"default": style});

var measureOptions = {
    handlerOptions: {
        style: "default", // this forces default render intent
        layerOptions: {styleMap: styleMap},
        persist: true
    }
};

tbar_items.measure = new OpenLayers.Control.Measure(OpenLayers.Handler.Path, measureOptions);

/**
 * Create the query results window. It will be hidden until we need it.
 * This is done inside a function which is called from Ext.OnReady.
 */
function buildQResultWin() {
    var pageWidth = Ext.getBody().getWidth()
    qResultWin = new Ext.Window({
        id: "qResultWin",
        width: 300,
        height: 200,
        pageX:pageWidth-(pageWidth*.25),
        pageY:50,
        autoScroll: true,
        closeAction: 'hide',
        items: [new Ext.grid.GridPanel({
            store: new Ext.data.Store({
                proxy: new Ext.data.HttpProxy({
                    url: Drupal.settings.freebase_path + '/assets/php/AjaxRouter.php'
                }),
                reader: new Ext.data.JsonReader({
                    totalProperty: "results",
                    root: "rows"
                    }, new Ext.data.Record.create([
                        {name: 'field'},
                        {name: 'value'}
                    ])
                )                
            }),
            columns: [
                {header:"Field", width:100, sortable:true, dataIndex:'field'},
                {header:"Value", width:200, sortable:false, dataIndex:'value'}
            ],
            sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
            autoHeight:true,
            frame:false,
            iconCls:'icon-grid',
            id: 'queryResultPanel',
            hidden: false
        }),{
            xtype: 'panel'
            ,id: 'queryResultLoading'
            ,layout: 'absolute'
            ,items: [{
               xtype: 'panel'
               ,border: false
               ,x: 60
               ,y: 65
               ,html: "<img src='" + Drupal.settings.freebase_path + "/assets/images/large-loading.gif'/>"
            },{
               xtype: 'panel'
               ,border: false
               ,x: 100
               ,y: 72
               ,html: "<span style='font-size:14px; font-weight:bold;'>Loading...</span>" 
            }]   
            ,height: 180 
            ,hidden: true
        },{
            xtype: 'panel'
            ,id: 'queryResultNotFound'
            ,html: 'No results could be found for that location'
            ,hidden: true
        }] 
    });
}
    // Set up custom controls

// point query
OpenLayers.Util.extend(tbar_items.pointQuery, 
    new OpenLayers.Handler.Click(tbar_items.pointQuery, { 
        click: function(evt) {

            // clear the scratch layer
            ScratchLayer.getInstance().clear();

            var geom = new Geometry();
            geom.setCenter(evt.xy, 10);

            // Get an array of visible queryable layers.
            var eligibleLayers = getVisibleQueryableLayers();

            if (eligibleLayers.length == 1) {
                // There's only one visible queryable layer. Do the query.
                eligibleLayers[0].pointQuery(geom);
            } else if (eligibleLayers.length == 0) {
                // There are no visible and queryable layers. Notify the user.
                Ext.Msg.show({
                    title: "Query Results", 
                    msg: "<b>Please activate a queryable layer:</b><br>" + getQueryableLayers(),
                    buttons: Ext.Msg.OK
                });
            } else {
                // There are more than one visible and queryable layers. 
                // First, determine which if any layers near the user's click point
                // contain data

                // Put up a loading div for the menu items -- This doesn't work because
                // the loading div is buried under the google map
                var loadingDiv = Ext.get('small-loading-indicator');
                var docPosition = getDocumentPosition(evt.xy, map);
                loadingDiv.setXY([docPosition.x + 20, docPosition.y + 20]);
                loadingDiv.setVisible(true);
                loadingDiv.show();

                // Do the AJAX request for the menu items
                Ext.Ajax.request({
                    url: Drupal.settings.freebase_path + '/assets/php/AjaxRouter.php',
                    success: function(result, request) {
                        loadingDiv.setVisible(false);
                        doPointQuery(result.responseText, geom, [docPosition.x, docPosition.y]);
                    },
                    failure: ajaxFailure,
                    params: {
                        func: 'getRelevantLayers',
                        geom: geom.getGeometryText(map), // Box for oracle
                        center: geom.getCenterGeomText(map), // Center pt for postgres
                        meta: false,
                        view: JSON.stringify(getLayerNames(getVisibleQueryableLayers()))
                    },
                    method: 'POST'
                });
            }
        }
    })
);

// add a deactivate functions to the pointQuery
OpenLayers.Util.extend(tbar_items.pointQuery, {
    deactivate: function() {
        queryMenu.items.get('pointQueryMenuItem').setChecked(false, true);
        document.body.style.cursor='default';
    }
});

/**
function updateActiveWin(){
    var vizLayers = getActiveLayers();
    console.log(vizLayers);
    if (activeLayerWin.isVisible() && vizLayers.length < 0){
        //activeLayerWin.close();
        //buildActiveLayerWin();
        //activeLayerWin.show();
    } else {
        buildActiveLayerWin();
    }
}

function getActiveLayers(){
    var eLayers = getVisibleQueryableLayers(); //getQueryableLayerArray();
    var elayer_checks = [];
    for (var i =0; i < eLayers.length; i++){
        check = false;
        if (i == 0) {
            activeLayer = eLayers[i];
            var check = true;
        }
        radio = {
            boxLabel:eLayers[i].display_name,
            name:'active_layer',
            inputValue:eLayers[i].name,
            checked:check
        }
        elayer_checks.push(radio);
    }
    return elayer_checks;
}


function buildActiveLayerWin(){
    var pageWidth = Ext.getBody().getWidth();
    var vlayers = getActiveLayers(); 

    activeLayerWin = new Ext.Window({
        title:'Set the active layer',
        id:'activeLayerWin',
        closeAction:'hide',
        width:300,
        autoHeight:true,
        pageX:pageWidth-(pageWidth*.75),
        pageY:50,
        bodyStyle:'font-size:8px;',
        listeners:{
            'hide':function(){
                deactivateControl('pointQuery');
            }
        },
        items:[new Ext.form.FormPanel({
            id:'radio_checks',
            hidden:false,
            border:false,
            labelWidth:1,
            labelSeparator:'',
            defaultType: 'radio',
            defaults:{labelSeparator:''},
            items:vlayers
        })]
    });

}
*/


    // rubber band box query
OpenLayers.Util.extend(tbar_items.boxQuery, {
    draw: function() {
        this.box = new OpenLayers.Handler.Box(tbar_items.boxQuery,
            {"done": this.notice}
        );
    },
    activate: function() {
        this.box.activate();
    },
    deactivate: function() {
        this.box.deactivate();
        queryMenu.items.get('boxQueryMenuItem').setChecked(false, true);
        document.body.style.cursor='default';
    },
    notice: function (bounds) {
        // clear the scratch layer
        ScratchLayer.getInstance().clear();

        // If the user clicked a single point, just return
        if (bounds.left == null || bounds.right == null ||
            bounds.top == null || bounds.bottom == null) {
           return;
        }

        // Create a geometry object from the bounds
        var geom = new Geometry();
        geom.setBounds(new OpenLayers.Pixel(bounds.left, bounds.bottom),
                       new OpenLayers.Pixel(bounds.right, bounds.top));

        var geomText = geom.getGeometryText(map);
        var layersToQuery = false;
        
        // For each layer, call addTab to set up the query results tab
        for (layer in layerArray) {
            if (layerArray.hasOwnProperty(layer)) {
                if (layerArray[layer] instanceof FreebaseLayer &&
                    layerArray[layer].getVisibility() && 
                    layerArray[layer].isQueryable()) {
                    addTab(layerArray[layer], geomText);
                    layersToQuery = true;
                }
            }
        }

        // If there were no queryable layers, notify the user
        if (!layersToQuery) {
            Ext.Msg.show({
                title: "Query Results", 
                msg: "<b>Please activate a queryable layer:</b><br>" + getQueryableLayers(),
                buttons: Ext.Msg.OK
            });
        }
    }
});


var queryMenu = new Ext.menu.Menu({
        id: 'queryMenu',
        defaults:{bodyStyle:'border:1px solid red;'},
        items: [{
            text: 'By Point',
            id: 'pointQueryMenuItem',
            checked: false,
            group: 'query_grp',
            checkHandler: function() {
                //activeLayerWin.show();
                activateControl('pointQuery');
                var cur = "/assets/images/cursors/query_point_1632.cur";
                document.body.style.cursor = "url('"+ Drupal.settings.freebase_path + cur +"'), default";
            }
        },{
            text: 'By Region',
            id: 'boxQueryMenuItem',
            checked: false,
            group: 'query_grp',
            checkHandler: function() {
                activateControl('boxQuery');
                var cur = "/assets/images/cursors/query_region_1632.cur";
                document.body.style.cursor = "url('"+ Drupal.settings.freebase_path + cur +"'), default";
            }
        },{
            text: 'Clear Results'
            ,id: 'clearOverlaysMenuItem'
            ,handler: function() {
               ScratchLayer.getInstance().clear();
               layerArray['markers'].clearMarkers(); // Clear the markers from 'find location'
            }
        }]
    });


 
function getToolbar(){
 
    toolbar = [
        new Ext.Action({
            text: 'Home',
            pressed: false,
            icon: Drupal.settings.freebase_path +'/assets/images/icons/house.gif',
            iconCls:'nav',
            handler: function() {
                map.setCenter(latlon, zoom);
                layerArray['markers'].clearMarkers(); // Clear the markers from 'find location'
            }
        }),
        new Ext.Action({
            text: 'Pan',
            toggleGroup: 'tool_grp',
            pressed: true,
            icon:Drupal.settings.freebase_path + '/assets/images/icons/pan.gif',
            iconCls:'nav',
            handler: function() {
                deactivateControl('all');
                var cur = "/assets/images/cursors/pan_1632.cur";
                document.body.style.cursor = "url('"+ Drupal.settings.freebase_path + cur +"'), default";
            }
        }),
        new Ext.Action({
            text: 'Zoom',
            toggleGroup: 'tool_grp',
            pressed: false,
            icon: Drupal.settings.freebase_path + '/assets/images/icons/zoom.png',
            iconCls:'nav',
            handler: function() {
                activateControl('zoombox');
                var cur = "/assets/images/cursors/zoom_1632.cur";
                document.body.style.cursor = "url('"+ Drupal.settings.freebase_path + cur +"'), default";
            }
        }),
        new Ext.Action({
            text: 'Measure',
            pressed: false,
            id: 'measureButton',
            toggleGroup: 'tool_grp',
            icon: Drupal.settings.freebase_path +'/assets/images/icons/measure.gif',
            iconCls:'nav',
            handler: function() {
                openMeasure();
                activateControl('measure');
                var cur = "/assets/images/cursors/measure2_1632.cur";
                document.body.style.cursor = "url('"+ Drupal.settings.freebase_path + cur +"'), default";
            }
        }),
        new Ext.Action({
            text: 'Print',
            id: 'printButton',
            pressed: false,
            disabled:true,
            icon: Drupal.settings.freebase_path +'/assets/images/icons/printer.gif',
            iconCls:'nav',
            handler: function() {
                printMap(); 
            }
        }),
        new Ext.Action({
            text: 'Help',
            id: 'helpButton',
            pressed: false,
            disabled:true,
            icon: Drupal.settings.freebase_path +'/assets/images/icons/help.gif',
            iconCls:'nav',
            handler: function() {
                if (typeof doHelp != "undefined") {
                   doHelp();
                }
            }
        }),
        new Ext.Action({
            text: 'Find Location',
            pressed: false,
            icon: Drupal.settings.freebase_path +'/assets/images/icons/find.gif',
            iconCls:'nav',
            handler: function() {
                openSearch();
            }
        }),
        new Ext.Action({
            text: 'Query',
            toggleGroup: 'tool_grp',
            icon: Drupal.settings.freebase_path +'/assets/images/icons/query2.gif',
            iconCls:'nav',
            menu: queryMenu
        })
    ]
    if(Drupal.settings.uid > 0) {
      toolbar.push(
        new Ext.Action({
            text: 'Logout',
            icon: Drupal.settings.freebase_path +'/assets/images/icons/door_in.gif',
            iconCls:'nav',
            handler: function() {
              window.location = Drupal.settings.basePath + 'logout';
            }
        })
      );
    }
    

    return toolbar;
}

/**
 *  Create the BaseLayer menu for the right side tbar
 *  This will toggle the different google baselayers
 */
 var baseMenu =  new Ext.menu.Menu({
        id: 'baseMenu',
        items: [{
            text: 'Map',
            group:'base',
            checked: true,
            handler: function() {
                map.setCenter(map.getCenter(), map.getZoom());
                gbase.map.setBaseLayer(gbase);
                map.baseLayer.setVisibility(true);
            }
        },{
            text: 'Satellite',
            group:'base',
            checked: true,
            handler: function() {
                map.setCenter(map.getCenter(), map.getZoom());
                gsat.map.setBaseLayer(gsat);
                map.baseLayer.setVisibility(true);
            }
        },{
            text: 'Hybrid',
            group:'base',
            checked: false,
            handler: function() {
                map.setCenter(map.getCenter(), map.getZoom());
                ghybrid.map.setBaseLayer(ghybrid);
                map.baseLayer.setVisibility(true);
            }
        },{
            text: 'None',
            group:'base',
            checked: false,
            handler: function() {
                map.setCenter(map.getCenter(), map.getZoom());
                map.baseLayer.setVisibility(false);
            }
        }]
    }); 


/**
 * Activate the specified tool; deactivate others
 */
function activateControl(control) {
    for (thisControl in tbar_items) {
        if (thisControl == control) {
            tbar_items[thisControl].activate();
        } else {
            tbar_items[thisControl].deactivate();
        }
    }
}

/**
 * Deactivate the specified tool
 */
function deactivateControl(control) {
    if (control == 'all') {
        var cur = "/assets/images/cursors/pan_1632.cur";
        document.body.style.cursor = "url('"+ Drupal.settings.freebase_path + cur +"'), default";
        for (thisControl in tbar_items) {
            tbar_items[thisControl].deactivate();
        }
    } else {
        tbar_items[control].deactivate();
    }
}

/**
 * Add a tab to the results area for the given layer
 * @param {FreebaseLayer} layer
 * @param {OpenLayers.LonLat} bottom-left box coordinate
 * @param {OpenLayers.LonLat} top-right box coordinate
 */
function addTab(layer, geom) {
    viewport.findById('qresult_panel').add(
      layer.query(geom)
    ).show();
    viewport.findById('qresult_panel').expand();
}

/**
 * If there are multiple visible queryable layers, this function handles the return
 * from the ajax call to getRelevantLayers. If there are multiple relevant (Visible,
 * Queryable, and containing data near the user's click point) layers, let the user
 * choose which layer to query. Otherwise, perform the query on the relevant layer
 * or display a message
 * @param {String} JSON string representing an array of layer view names for relevant layers
 * @param {Object} Geometry object representing the user's click
 * @param {Object} XY location of user's click - used to determine where to put the layer menu
 */
function doPointQuery(layerJSON, geom, menuLocation) {
    // Convert the json to an array
    var layers = JSON.parse(layerJSON);

    // If there are no layers returned, notify the user
    if (layers == null) {
        Ext.Msg.show({
            title: "No Results Found", 
            msg: "<b>No data was found near that location.</b><br>",
            buttons: Ext.Msg.OK
        });
        return;
    }

    // If there is only one layer, do the query
    if (layers.length == 1) {
        // The PHP returns an array of view names, we need to get the FreebaseLayer objects
        var layerObj = getLayersByName(layers);
        layerObj[0].pointQuery(geom);
        return;
    }

    // If there are more than one relevant layers, ask the user which one to query
    if (layers.length > 1) {
        // The PHP returns an array of view names, we need to get the FreebaseLayer objects
        var layerObj = getLayersByName(layers);

        // Build a popup menu to ask the user which layer to query
        var menu = new Ext.menu.Menu({
            id: 'layerMenu',
            defaults:{bodyStyle:'border:1px solid red;'}
        });

        // Get a menuItem for each layer
        for (var i in layerObj) {
            if (!layerObj.hasOwnProperty(i)) continue;

            // define a handler for our button
            var handler = function () {
                this.layerObj.pointQuery(geom); // 'this' refers to the button here
            }
            menu.add(layerObj[i].getMenuItem(handler)); 
        }

        menu.showAt(menuLocation);
    }
}


