/** Event handler for onmousedown event on the menu drag hook
 * @param e the event
 */
function menu_startDrag(e){
    if(!e){var e=window.event};

    var targ = document.getElementById('layerBox');
 
    offsetX=e.clientX;
    offsetY=e.clientY;

    if(!targ.style.left){targ.style.left='15px'};
    if(!targ.style.top){targ.style.top='45px'};

    coordX=parseInt(targ.style.left);
    coordY=parseInt(targ.style.top);

    drag=true;
    targ.onmousemove=menu_dragDiv;
}

/** Event handler for onmousemove event on the menu drag hook
 * @param e the event
 */
function menu_dragDiv(e){
    if(!drag){return};
    if(!e){var e=window.event};
    
    var targ = document.getElementById('layerBox');
    targ.style.left=coordX+e.clientX-offsetX+'px';
    targ.style.top=coordY+e.clientY-offsetY+'px';
    return false;
}

/** Event handler for onmouseup event on the menu drag hook
 */
function menu_stopDrag(){
    drag=false;
}

/**
 * @constructor
 * @param name the name of the contact
 * @param email the email address for the contact
 */
function Contact(name, email){
  /** @type String */
  this.name = name;
  /** @type String */
  this.email = email;
}

/**
 * @constructor
 * @param epsg the Epsg object
 * @param dimension the dimensions of the map
 */
function Menu(epsg,dimension){

    /** @type Array */
    this.contacts = new Array();
    /** @type Epsg */
    this.epsg = epsg;
    /** @type Dimension */
    this.dimension = dimension;

    this.toggle = menu_toggle;
    this.viewLayerSelection = menu_viewLayerSelection;
    this.viewLayerOrder = menu_viewLayerOrder;
    this.viewBackgroundLayers = menu_viewBackgroundLayers;
    this.viewCountryLayers = menu_viewCountryLayers;
    this.viewUserLayers = menu_viewUserLayers;
    this.viewAbout = menu_viewAbout;
    this.changeCountry = menu_changeCountry;

    this.deleteLayer = menu_deleteLayer;
    this.deleteLayerGroup = menu_deleteLayerGroup;

    this.order = menu_order;
    this.orderDone = menu_orderDone;
    this.getSelectedGid = menu_getSelectedGid;
    
    this.addContact = menu_addContact;
    this.setHookHTML = menu_setHookHTML;
    
    this.getSelectionMenuHTML = menu_getSelectionMenuHTML;
    this.getInfoHTML = menu_getInfoHTML;
    this.getLayerGroupHTML = menu_getLayerGroupHTML;
    this.getLayersHTML = menu_getLayersHTML;

    this.setBackground = menu_setBackground;
    this.setUserDefined = menu_setUserDefined;
    this.setCountries= menu_setCountries;

    this.toggleAllSelect= menu_toggleAllSelect;

    this.adjustSize= menu_adjustSize;
    
    /** @type int */
    this.defaultMenu = 1;
    /** @type int */
    this.defaultSubMenu = 2;
    /** @type String */
    this.defaultBorder = '#DDDDDD';

    /** @type boolean */
    this.selectAllCountries = false;
    /** @type String */
    this.selectedCountry = '';

    /** Width of this menu. @type int */
    this.width = 300;

    /** Height of the scroll div with tools at bottom of menu, (country layers). @type int */
    this.scrollHeightTools = this.dimension.height-127;

    /** Height of scroll div without tools, background and overlay. @type int */
    this.scrollHeight = this.dimension.height-80;
}

function menu_deleteLayer(id){
    map.userDefined.deleteLayer(id);
    this.viewUserLayers();
    map.redraw();
}

function menu_deleteLayerGroup(id){
    map.userDefined.deleteLayerGroup(id);
    this.viewUserLayers();
    map.redraw();
}


/** Get what's selected in the layer order page.
 * @return an Array with string lay or grp at position 0, layer gid or layer group gid
 *         at position 1
 */
function menu_getSelectedGid(){
    var form = document.orderForm;
    var inputs = form.getElementsByTagName('input');
    for( var i = 0; i< inputs.length; i++){
        var inp = inputs[i];
        if( inp.name=='gid' && inp.checked ){        
            var parts = inp.value.split(':');
            return parts;  
        }
    }    
    return -1;
}

/** Moves the currently selected layer/layergroup in 
 * the layer order page, either up or down.
 * @param direction string with value 'up' or 'down'
 */
function menu_order(direction){
    var gidParts = this.getSelectedGid();

    if(gidParts==-1)
        return;

    if(gidParts[0]=='lay'){
        var layer = lookupLayer(gidParts[1]);
        var layGrp = getLayerGroupForLayer(layer); 
        if(direction=='up')
            layGrp.moveLayerUp(gidParts[1]);
        else if(direction=='down')
            layGrp.moveLayerDown(gidParts[1]);
    }
    else if(gidParts[0] == 'grp'){
        if(direction=='up')
            moveLayerGroupUp(gidParts[1]);
        else if(direction=='down')
            moveLayerGroupDown(gidParts[1]);
    }
    else{
        alert('Wrong gidParts[0] = '+gidParts[0]);
        return;
    }
    this.viewLayerOrder(gidParts[0], gidParts[1]);
}

/** Confirms when the layer ordering is finished. 
 * Calls the redraw function on the map variable.
 */
function menu_orderDone(){
    map.redraw();
}

/**
 * Function to be called after the DOM element 'layerBox' has been
 * created to adjust the size of the menu.
 */
function menu_adjustSize(){
    var layerBox = document.getElementById('layerBox');
    layerBox.style.width = this.width;
    layerBox.style.height = this.dimension.height-15;    
}

/**
 * Toggles the selectAllCountries flag (true/false)
 */
function menu_toggleAllSelect(){   
   this.selectAllCountries = !this.selectAllCountries ;   
}

/**
 * Called by onchange event for the country select to
 * change selected country. Function viewCountryLayers is executed.
 * @param select the country select tag
 */
function menu_changeCountry(select){
    var option = select.options[select.selectedIndex];
    this.viewCountryLayers( option.value );
}

/**
 * Set a reference to the UserDefined object
 * @param userDefined the UserDefined object
 */
function menu_setUserDefined(userDefined){
    this.userDefined = userDefined;
}

/**
 * Set a reference to the countries array
 * @param countries the array with countries
 */
function menu_setCountries(countries){
    this.countries = countries;
}

/**
 * Set a reference to the Background object
 * @param background the background object
 */
function menu_setBackground(background){
    this.background = background;
}

/**
 * Add a contact to this menu
 * @param contact the Contact object to be added
 */
function menu_addContact(contact){
    this.contacts[ this.contacts.length ] = contact;
}

/**
 * Sets the innerHTML attribute of element <code>layerBoxHook</code>
 * @param html the html text
 */
function menu_setHookHTML(html){
    var hook = document.getElementById('layerBoxHook');
   
    hook.innerHTML = html;   
}

/**
 * Views the about/information page
 */
function menu_viewAbout(){
    var html = this.getInfoHTML();
    this.setHookHTML(html);
}

/**
 * Views the layer order page and checks radiobutton for layer or layergroup
 * specified by parameters.
 * @param type string 'grp' or 'lay'
 * @param gid the id for layergroup or layer
 */
function menu_viewLayerOrder(type, gid){
    var html = '';
    html += '<form name="orderForm">';
    html += '<div id="scrollHolder" style="width: '+this.width+'px; height: '+this.scrollHeight+'px;"><div id="scroller" style="width: '+this.width+'px; height: '+this.scrollHeight+'px;">';
    html += '<ul class="orderList">';
    var numVisibleLayers = 0;

    g_orderedLayerGroups = getOrderedLayerGroups();

    for(var i = 0; i < g_orderedLayerGroups.length ; i++){
        var layerGroup = g_orderedLayerGroups[i];

        if( layerGroup.hasVisibleLayer() ){
           
            var checked = '';
            if(type=='grp' && gid == layerGroup.gid){
                checked = 'checked';
            }
            html += '<li><input '+checked+' type="radio" name="gid" value="grp:'+layerGroup.gid+'">';
            html += layerGroup.title+'<ul>';

            for(var j=layerGroup.layers.length-1; j >= 0; j--){
                var layer = layerGroup.layers[j];

                if( layer.visible ){
                    checked = '';
                    if(type=='lay' && gid == layer.gid){
                        checked = 'checked';
                    }
                    
                    html += '<li><input '+checked+' type="radio" name="gid" value="lay:'+layer.gid+'">'+layer.displayName+'</li>';
                    numVisibleLayers++;
                }                
            }
            html += '</ul></li>';
        }       
    }

    if(numVisibleLayers==0){
        html += '<li>No visible layers</li>';
    }
    html += '</ul>';
    html += '</div></div>';
    html += '<input type="button" value="'+i18n('js.menu.down')+'" onclick="map.menu.order(\'down\');">';
    html += '<input type="button" value="'+i18n('js.menu.up')+'" onclick="map.menu.order(\'up\');">';
    html += '<input type="button" value="'+i18n('js.menu.done')+'" onclick="map.menu.orderDone();">';    
    html += '</form>';

    this.setHookHTML(html);
}

/**
 * Views the layer selection page and selects the country submenu
 */
function menu_viewLayerSelection(){      
    this.viewCountryLayers();
    mark('submenu',this.defaultSubMenu, this.defaultBorder);
}

/**
 * Views the background layers page, including the submenu.
 */
function menu_viewBackgroundLayers(){
    var html = this.getLayerGroupHTML(this.background.groups, false);
    var menu = this.getSelectionMenuHTML();

    this.setHookHTML(menu+html);
}

/**
 * Views the country layers page, including the submenu. If parameter
 * isn't specified, the first country's layers will be viewed. Layers
 * is grouped in categories.
 * @param code the countrycode for which country to view layers
 */
function menu_viewCountryLayers(code){

    var html = this.getSelectionMenuHTML();

    if( !code ){
        code = this.selectedCountry;
    }

    var selectedCode = '';

    html += i18n('js.menu.country')+': <select onchange="javascript: map.menu.changeCountry(this);">';
    for(var i=0;i < this.countries.length; i++){
        var country = this.countries[i];

        if( !selectedCode ){
            selectedCode = country.code;
        }

        var sel = '';
        if( code == country.code ){
            sel = 'selected';
            selectedCode = country.code;
        }
        html += '<option value="'+country.code+'" '+sel+'>'+country.name+'</option>';
    }
    html += '</select><br>';
    
    this.selectedCountry = selectedCode;
    
    // group layers in categories
    for(var i=0 ; i < this.countries.length ; i++){
        var country = this.countries[i];
        if( country.code == selectedCode ){
 
            html += '<div id="scrollHolder" style="width: '+this.width+'px; height: '+this.scrollHeightTools+'px;"><div id="scroller" style="width: '+this.width+'px; height: '+this.scrollHeightTools+'px;">';

            for( var j = 0; j < country.categories.length; j++){
                var category = country.categories[j];

                var checked = '';
                if(category.allChecked)
                    checked = 'checked="true"';
                html += '<h2 class="lg-header"><input type="checkbox" '+checked+' title="'+i18n('js.menu.checkall')+'" onclick="map.toggleCategory('+category.id+')">'+category.title+'</h2>';
                html += this.getLayersHTML( category.layers,country.groups[0].gid ,'cat:'+category.id,false);
            }
            
            html += '</div></div>';

            // add some tools
            html += '<div id="menuTools"><input type="image" src="images/icon_zoom.gif" onclick="map.countryExtent(\''+country.code+'\');" title="'+i18n('js.menu.zoomctry')+'">';
            // add a capability tool for each layer group
            for( var j = 0; j < country.groups.length; j++){
                var group = country.groups[j];
                html += '<input type="image" src="images/capabilities.gif" onclick="map.openCapabilities(\''+group.gid+'\');" title="'+i18n('js.menu.capfor')+' '+group.title+'">';
            }
            break;
        }
    }    

    var checked = '';
    if( this.selectAllCountries )
      checked = 'checked';

    html += '<br><input '+checked+' type="checkbox" id="checkAllCountries" onclick="map.menu.toggleAllSelect();">'+i18n('js.menu.selall');
    html += '</div>';
    this.setHookHTML(html);
}

/**
 * Views the user defined layers page, including the submenu.
 */
function menu_viewUserLayers(){
    var html = this.getLayerGroupHTML( this.userDefined.groups, true);
    var menu = this.getSelectionMenuHTML();
    this.setHookHTML(menu+html);
}

/**
 * Creates html for the layers specified.
 * <p>
 * Example:<br>
 * <pre>
 *  [radio_butto] [checkbox] Layer Name 1
 *  [radio_butto] [checkbox] Layer Name 2
 *  ...
 * </pre>
 * A layer radio button is checked if that layer is the active layer. A layer
 * checkbox is checked if layer is visible.
 * @param layers an array of Layer objects
 * @return the generated html
 * @type String
 */
function menu_getLayersHTML(layers, groupId, checkboxPrefix, showDelete){
   
    var html = '';
    for( j = 0; j < layers.length; j++){

        var layer = layers[j];
       
        var checked  = '';
        if(layer.gid == map.activeLayerId)
            checked = 'checked="true"';
        html += '<input type="radio" name="active" '+checked+' onclick="javascript: map.setActiveLayer('+layer.gid+');">';

        checked = '';
        if(layer.visible)
            checked = 'checked="true"';

        html += '<input id="'+checkboxPrefix+':'+layer.gid+'" type="checkbox" '+checked+' onclick="javascript: map.toggleLayer('+layer.gid+');">';


        html += '<a title="'+i18n('js.menu.styles')+'" href="javascript: map.openStyle( '+groupId+' , '+layer.gid+');">' +layer.displayName + '</a>';
        if(showDelete){ 
            html += ' <span class="del">(<a href="javascript:map.menu.deleteLayer('+layer.gid+');">'+i18n('js.menu.delete')+'</a>)</span>';
        }
        html += '<br>';

      
    }
    return html;
}

/**
 * Creates html for the layer groups specified.
 * @param groups an array of LayerGroup objects
 * @return the generated html
 * @type String
 */
function menu_getLayerGroupHTML(groups, showDelete){
    var html = '';
    html += '<div id="scrollHolder" style="width: '+this.width+'px; height: '+this.scrollHeight+'px;"><div id="scroller" style="width: '+this.width+'px; height: '+this.scrollHeight+'px;">';

    for(var i = 0; i < groups.length; i++){
        layerGroup = groups[i];
        var checked = '';
        if(layerGroup.allChecked){
            checked = 'checked="true"';
        }
        html += '<h2 class="lg-header"><input type="checkbox" '+checked+' title="'+i18n('js.menu.checkall')+'" onclick="map.toggleLayerGroup('+layerGroup.gid+')">';
        html += '<input type="image" src="images/capabilities_mini.gif" onclick="map.openCapabilities(\''+layerGroup.gid+'\');" title="'+i18n('js.menu.opencap')+'"> '+layerGroup.title;
        if(showDelete){
            html += ' <span class="del">(<a href="javascript:map.menu.deleteLayerGroup('+layerGroup.gid+');">'+i18n('js.menu.delete')+'</a>)</span>';
        }
        html += '</h2>';
        html += this.getLayersHTML(layerGroup.layers,layerGroup.gid,'lay:'+layerGroup.gid,showDelete);
    }
    html += '</div></div>';
    return html;
}

/**
 * Creates html for the submenu (shown under layer selection)
 * @return the generated html
 * @type String
 */
function menu_getSelectionMenuHTML(){
    var html = '';
    html += '<div class="submenu">';
    html += '<a id="submenu1" href="javascript: map.menu.viewBackgroundLayers(); mark(\'submenu\',1, \''+this.defaultBorder+'\');">'+i18n('js.menu.backgrounds')+'</a>';
    html += '<a id="submenu2" href="javascript: map.menu.viewCountryLayers(); mark(\'submenu\',2, \''+this.defaultBorder+'\');">'+i18n('js.menu.countries')+'</a>';
    html += '<a id="submenu3" href="javascript: map.menu.viewUserLayers(); mark(\'submenu\',3, \''+this.defaultBorder+'\');">'+i18n('js.overlay')+'</a>';
    html += '</div>';
    return html;
}

/**
 * Shows/hides the layer menu, preselects the layer selection item
 */
function menu_toggle(){
    this.viewLayerSelection();

    mark('menu',this.defaultMenu, this.defaultBorder);

    var layerList = document.getElementById("layerBox");
    toggleVisibility( layerList );
}

/**
 * Creates html for the information/about table
 * @return generated html
 * @type String
 */
function menu_getInfoHTML(){
 
    var html = '';
    html += '<div style="text-align: center;"><table summary="information"><tr><td class="header" colspan="2">'+i18n('js.menu.info')+'</td></tr>';
    html += '<tr> <td colspan="2">EPSG ' + this.epsg.value + ' (' + this.epsg.description + ')</td></tr>';
    html += '<tr><td colspan="2">'+i18n('js.menu.clientversion')+': 1.2.0, 2005-02-10</td></tr>';
    html += '<tr><td colspan="2">'+i18n('js.menu.scalelimit')+': <input size="6" type="text" value="'+map.scaleLimit+'" onchange="map.setScaleLimit(this);"></td></tr>';
    html += '<tr><td valign="top" colspan="2">';
    html += '<form method="post">'+i18n('js.menu.width')+': <input type="text" size="3" name="width" value="'+this.dimension.width+'"> ';    
    html += '<input type="submit" value="'+i18n('js.menu.changewidth')+'"></form>';
    html += '</td></tr>';    
    html += '<tr><td class="header" colspan="2">'+i18n('js.menu.contacts')+'</td></tr>';

    for( var i = 0; i < this.contacts.length ; i++){
        contact = this.contacts[i];
        html += '<tr><td>'+contact.name+'</td><td>'+contact.email+'</td></tr>';
    }
    html += '</table></div>';
    return html;
}
