if ( window.hidari == undefined)
    window.hidari = new Object(); //create the hidari namespace

hidari.Menu = function() { //the Menu object constructor
    this.state = new Object(); //menu items selected
    this.state.upperRow = null;
    this.state.lowerRow = null;

    this.elements = new Object(); //elements created with MooTools

    this.upperRowId = 'menu_upper_row';
    this.lowerRowId = 'menu_lower_row';

    this.init = function (jsonObject) {
        this.elements = this.getElementRow('menu_item_', jsonObject, null);
        this.selectElement(this.elements);
    }

    this.getElementRow = function(idPrefix, jsonObject, parent) {
        var elementRow = new Object();
                for (var i = 0; i < jsonObject.length; i++) {
                    elementRow[idPrefix + i] = new Element('a', {
                        'id': idPrefix + i,
                        'html': jsonObject[i].text
                    });


                    /* This is a reference to the elements parent,
                     * according to the menu hierarchy.
                     * It eanbles graphicaly selecting the parent */
                    elementRow[idPrefix + i].parent = parent;

                    /* the event handler functions are called by the events
                     * and not by the Menu object
                     * so the 'this' keyword inside of them
                     * refers to the events (the callers) */

                    /* Forced to use global MENU
                     * instead of 'this' keyword
                     * because of the recursion */
                    elementRow[idPrefix + i].addEvent('mouseover', MENU.mouseOverHandler);
                    elementRow[idPrefix + i].addEvent('mouseout', MENU.mouseOutHandler);
                    elementRow[idPrefix + i].addEvent('click', MENU.clickHandler);

                    if (jsonObject[i].submenu) { //if has submenu
                        elementRow[idPrefix + i].appendText('...'); //for usability
                        elementRow[idPrefix + i].set('nohref', '');
                        elementRow[idPrefix + i].submenu = this.getElementRow( //recursion for submenus
                            idPrefix + i,
                            jsonObject[i].submenu,
                            elementRow[idPrefix + i]
                        );
                    } else { //no submenu
                        elementRow[idPrefix + i].set('href', jsonObject[i].url);
                    }
                }
        return elementRow;
    }

    this.injectRow = function(elementRow, containerId){
        var children = $(containerId).getChildren();
        for (var i = 0; i < children.length; i++)  //empty the container
            children[i].dispose(); //remove element from DOM

        for (var x in elementRow)
            elementRow[x].inject($(containerId));
    }

    this.selectElement = function(elementRow) {
        var windowUrl = location.href.replace(new RegExp('http://www.'), 'http://');
        windowUrl = windowUrl.replace(new RegExp('page/[0-9]+/'), ''); //paginated front page
        windowUrl = windowUrl.replace(new RegExp('[0-9]{4}/[0-9]{2}/[0-9]{2}/.*'), ''); //single post
        //alert(windowUrl);
        var matchFound = false;
        for (var x in elementRow) {
            if (elementRow[x].get('href') == windowUrl) { //found a match
                elementRow[x].addClass('selected');
                matchFound = true; //for recursion
                /* Using the global MENU because of the recursion */
                if (null  == elementRow[x].parent) {
                    MENU.state.upperRow = elementRow[x]; //remember the selected element
                    MENU.injectRow(elementRow, MENU.upperRowId);
                }
                else {
                    MENU.state.lowerRow = elementRow[x]; //remember the selected element
                    MENU.injectRow(elementRow, MENU.lowerRowId);
                }
            } else {
                if (elementRow[x].submenu) { //if has submenu
                    if(this.selectElement(elementRow[x].submenu)){ //match found in submenu (recursion)
                        elementRow[x].addClass('selected'); //select the parent
                        /* Using the global MENU because of the recursion */
                        MENU.state.upperRow = elementRow[x]; //remember the selected element
                        MENU.injectRow(elementRow, MENU.upperRowId);
                        matchFound = true;
                    }
                }
            }
        }
        return matchFound;
    }

    this.mouseOverHandler = function() {
        if (this.get('class') == 'selected')
            this.set('class', 'selected_hover');
        else
            this.set('class', 'hover');
    }

    this.mouseOutHandler = function() {
        if (this.get('class') == 'selected_hover')
            this.set('class', 'selected');
        else
            this.erase('class');
    }

    this.clickHandler = function() {
        if(this.get('class') != 'selected_hover') { //if not selected
            this.set('class', 'selected_hover'); //select
            /* using global var to acces
             * the method's parent object MENU
             * becaue this refers to the event 'this' */
            if (null == this.parent) { //if belongs to upper row
                /* The upper row
                 * alway has a selected element */
                MENU.state.upperRow.erase('class'); //deselect old element
                MENU.state.upperRow = this; //remember the new element

                if (this.submenu) { //if has submenu
                    MENU.injectRow(this.submenu, MENU.lowerRowId)
                }
            } else { //if belongs to lower row
                if (MENU.state.lowerRow) //if something is selected
                    MENU.state.lowerRow.erase('class'); //deselect old element

                MENU.state.lowerRow = this; //remember the new element
            }
        }
    }
}
