
var daseq = {};

/* ############### >>> CONFIG ################# */
daseq.config = {
    debug_mode: true
};

daseq.xmlrpc = importModule("xmlrpc");
daseq.service_url= 'http://www.daseq.de/daseq_service';
daseq.service = new daseq.xmlrpc.ServiceProxy(daseq.service_url, []);


/* ############### >>> UTILS ################# */
daseq.utils = {
    // from http://www.gerd-riesselmann.net
    // Adds eventhandler to given object

    addEvent: function(obj, evType, fn){
        if (obj.addEventListener)
        {
            obj.addEventListener(evType, fn, false);
            return true;
        }
        else if (obj.attachEvent)
        {
            var r = obj.attachEvent("on"+evType, fn);
            return r;
        }
        else
        {
            return false;
        }
    },

    getElementsByClassName: function(class_name){
        var all_obj,ret_obj=new Array(),j=0,teststr;
        if(document.all)all_obj=document.all;
        else if(document.getElementsByTagName && !document.all)all_obj=document.getElementsByTagName("*");
        for(i=0;i<all_obj.length;i++)
        {
            if(all_obj[i].className.indexOf(class_name)!=-1)
            {
            teststr=","+all_obj[i].className.split(" ").join(",")+",";
            if(teststr.indexOf(","+class_name+",")!=-1)
            {
                ret_obj[j]=all_obj[i];
                j++;
            }
            }
        }
        return ret_obj;
    },

    /*
    Copyright Robert Nyman, http://www.robertnyman.com
    Free to use if this text is included
    */
    getElementsByAttribute: function (oElm, strTagName, strAttributeName, strAttributeValue){
        var arrElements = (strTagName == "*" && document.all)? document.all : oElm.getElementsByTagName(strTagName);
        var arrReturnElements = new Array();
        var oAttributeValue = (typeof strAttributeValue != "undefined")? new RegExp("(^|\s)" + strAttributeValue + "(\s|$)") : null;
        var oCurrent;
        var oAttribute;
        for(var i=0; i<arrElements.length; i++){
            oCurrent = arrElements[i];
            oAttribute = oCurrent.getAttribute(strAttributeName);
            if(typeof oAttribute == "string" && oAttribute.length > 0){
                if(typeof strAttributeValue == "undefined" || (oAttributeValue && oAttributeValue.test(oAttribute))){
                    arrReturnElements.push(oCurrent);
                }
            }
        }
        return arrReturnElements;
    },

    // from http://jibbering.com/faq/faq_notes/closures.html#clSto
    associateObjWithEvent: function(obj, methodName){
        /* The returned inner function is intended to act as an event
        handler for a DOM element:-
        */
        return (function(e){
            /* The event object that will have been parsed as the - e -
            parameter on DOM standard browsers is normalised to the IE
            event object if it has not been passed as an argument to the
            event handling inner function:-
            */
            e = e||window.event;
            /* The event handler calls a method of the object - obj - with
            the name held in the string - methodName - passing the now
            normalised event object and a reference to the element to
            which the event handler has been assigned using the - this -
            (which works because the inner function is executed as a
            method of that element because it has been assigned as an
            event handler):-
            */
            return obj[methodName](e);
        });
    },

    bindToObject: function(obj, methodName){
        return (function(arg1){
            return obj[methodName](arg1);
        });
    },

    getComputedStyle: function(obj, property){
        if(window.getComputedStyle){
            return document.defaultView.getComputedStyle(obj,null).getPropertyValue(property)
        }
        else if(obj.currentStyle){
            return obj.currentStyle[property];
        }
    },

    dumpObject: function(obj){
        out = "<dl>";
        for (var attr in obj){
            out += "<dd>" + attr + ": <pre>" + obj[attr] + "</pre><\/dd>";
        };
        out += "<\/dl>";

        return out;
    },

    debug: function(msg){
        if(daseq.config.debug_mode == false){
            return;
        }
        var el = document.getElementById('debug');

        if(el){
            var first_child = el.firstChild;
            var container = document.createElement("div");
            
            var text = document.createTextNode(msg);
            container.appendChild(text);
            el.insertBefore(container, first_child);
        }
    },

    addHTMLAttribute: function(name, value, element){
        var attribute = document.createAttribute(name);
        attribute.nodeValue = value,
        element.setAttributeNode(attribute);
    },

    addCSSClass: function(value, element){
        var class_attr = element.attributes['class'];

        if(class_attr && class_attr.value){
            var class_value = class_attr.value;
            var found = false;

            var values = class_value.split(' ');
            for(i=0; i<values.length; i++){
                if (values[i] == value){
                    found = true;
                    break;
                }
            }
            if(!found) {
                values.push(value);
            }
            value = values.join(' ' );
        }

        var attribute = document.createAttribute('class');
        attribute.nodeValue = value;
        element.setAttributeNode(attribute);
    },

    removeCSSClass: function(value, element){
        var class_attr = element.attributes['class'];
        if(!class_attr){
            //element has no class attr
            return;
        }

        var class_value = class_attr.value;

        if(!class_value){
            //class value is empty
            return;
        }

        //filter out the value
        var a = new Array();
        var values = class_value.split(' ');
        for(i=0; i<values.length; i++){
            if (values[i] != value){
                a.push(values[i]);
            }
        }

        //overwrite class with new value
        var attribute = document.createAttribute('class');
        attribute.nodeValue = a.join(' ');
        element.setAttributeNode(attribute);
    }
};

/* ############### >>> static MenuHandler 'Class' ################# */
daseq.StaticMenuHandler = function(menuitem){
    daseq.utils.addEvent(menuitem, "mouseover", daseq.utils.associateObjWithEvent(this, 'mouseover_handler'));
    daseq.utils.addEvent(menuitem, "mouseout", daseq.utils.associateObjWithEvent(this, 'mouseout_handler'));
    this.menuitem = menuitem;
    this.timeout = null;
};


daseq.StaticMenuHandler.prototype.mouseover_handler = function(evt){
    daseq.utils.addCSSClass('hover', this.menuitem);
};

daseq.StaticMenuHandler.prototype.mouseout_handler = function(){
    daseq.utils.removeCSSClass('hover', this.menuitem);
};


/* ############### >>> MenuHandler 'Class' ################# */
daseq.MenuHandler = function(menuitem, path, menulevel){
    daseq.utils.addEvent(menuitem, "mouseover", daseq.utils.associateObjWithEvent(this, 'mouseover_handler'));
    daseq.utils.addEvent(menuitem, "mouseout", daseq.utils.associateObjWithEvent(this, 'mouseout_handler'));
    this.menuitem = menuitem;
    this.submenu = null;
    this.path = path;
    this.menulevel = menulevel;
    this.cached = false;
    this.pending = false;
    this.timeout = null
    
    // create a submenu for this menuitem
    //this.submenu = new daseq.SubMenu(menuitem);
};


daseq.MenuHandler.prototype.mouseover_handler = function(evt){
    if(this.timeout){
        window.clearTimeout(this.timeout);
    }

    daseq.utils.addCSSClass('hover', this.menuitem);

    if(!this.submenu && !this.cached && !this.pending){
        this.pending = true;
        var _callback_func = daseq.utils.bindToObject(this, 'get_submenu_callback');
        daseq.service.menu.get_submenu(this.path, this.menulevel, _callback_func);
    }
    else{
        this.show_submenu();
    }
};

daseq.MenuHandler.prototype.timeout_callback = function(){
    daseq.utils.removeCSSClass('hover', this.menuitem);
}

daseq.MenuHandler.prototype.mouseout_handler = function(evt){
    var _callback_func = daseq.utils.bindToObject(this, 'timeout_callback');
    this.timeout = window.setTimeout(_callback_func, 125);
};

daseq.MenuHandler.prototype.get_submenu_callback = function(result, err){
    this.pending = false;
    if (!err) {
        this.create_submenu(result.result);
    }
    else{
        daseq.utils.debug(err);
    }
};

daseq.MenuHandler.prototype.show_submenu = function(elements){
    if(this.submenu){
        this.submenu.style.visibility = 'visible';
    }

};


daseq.MenuHandler.prototype.create_submenu = function(elements){
    this.cached = true;
    if(!elements.length){
        return;
    }
//     var zone = document.createElement("div");
//     daseq.utils.addHTMLAttribute('class', 'zone', zone);
//     this.menuitem.appendChild(zone);

    var container = document.createElement("div");
    daseq.utils.addCSSClass('dynamic', container);

    var submenu_ul = document.createElement("ul");
    
    var zindex_counter = 1000;

    for(i=0;i<elements.length;i++){
        //crate the menuitems
        var submenu_li = document.createElement("li");
        daseq.utils.addHTMLAttribute('icoya:menulevel', elements[i].menulevel, submenu_li);
        daseq.utils.addHTMLAttribute('icoya:path', elements[i].path, submenu_li);
        daseq.utils.addHTMLAttribute('z-index', zindex_counter, submenu_li);
        zindex = zindex_counter-1;

        //create link_wrapper span element
        var link_wrapper = document.createElement("span")
        daseq.utils.addCSSClass('link_wrapper', link_wrapper);

        // create link element
        var link = document.createElement("a");
        //add link element attributes
        daseq.utils.addHTMLAttribute('href', elements[i].url, link);

        var link_content = document.createTextNode(elements[i].title);
        link.appendChild(link_content);


        //add link to link_wrapper
        link_wrapper.appendChild(link);
        //add link_wrapper to li-element
        submenu_li.appendChild(link_wrapper);
        //add li to ul
        submenu_ul.appendChild(submenu_li);
        
        // create MenuHandler for each link
        new daseq.MenuHandler(submenu_li, elements[i].path, elements[i].menulevel, this);
    }
    
    //add submenu to parent node of current menuitem
    container.appendChild(submenu_ul);
    this.submenu = container;
    this.menuitem.appendChild(container);
};




daseq.init_daseq = function(){
//     var menuitems = daseq.utils.getElementsByClassName('menuitem');
    var menuitems = daseq.utils.getElementsByAttribute(document.getElementById('menu'), 'li', 'icoya:menuitem', 'dynamic');
    for(i=0; i<menuitems.length; i++){
        
        var path = menuitems[i].getAttribute('icoya:path');
        var menulevel = menuitems[i].getAttribute('icoya:menulevel');
        new daseq.MenuHandler(menuitems[i], path, menulevel);
    }

    var menuitems_static = daseq.utils.getElementsByAttribute(document.getElementById('menu'), 'li', 'icoya:menuitem', 'static');
    for(i=0; i<menuitems_static.length; i++){
        new daseq.StaticMenuHandler(menuitems_static[i]);
    }
};

daseq.utils.addEvent(window, 'load', daseq.init_daseq);


