// JavaScript Document
var Utils = function(){};
Utils.debug_flag = false;
Utils.debug = function (message, colour){
    if(typeof(document.body)!="object" || document.body==null)return;
    if(!colour) var colour = "#000000";
    var div;
    var a;
    var a_t;
    if(!Utils.debug_flag) return true;
    if(!eval(div = document.getElementById("message_div"))){
        try {
            div = document.createElement("<div id=\"message_div\" style=\"width:200px; overflow:auto;padding:5px;text-align:left;position:absolute;top:400px;left:0px;border:1px solid #8a8a8a; background-color:#fed6c6;\">");
        }catch(e){
            div = document.createElement('div');
            div.setAttribute('id', "message_div");
            div.setAttribute('style', "width:200px; overflow:auto;padding:5px;text-align:left;position:absolute;top:400px;left:0px;border:1px solid #8a8a8a; background-color:#fed6c6;");
        }
        try {
            a = document.createElement("<a href=\"javascript:Utils.debug(null);\">");
        }catch(e){
            a = document.createElement('a');
            a.setAttribute('href', "javascript:Utils.debug(null);");
        } 
        a_t = document.createTextNode("Clear");
        a.appendChild(a_t);
        div.appendChild(a);
        
        document.body.appendChild(div);
        //alert(div.toSource());
    }
    if(message == null){
        while(div.hasChildNodes()){
            div.removeChild(div.firstChild);
        }
        div.parentNode.removeChild(div);
    }else{
        try {
            var p = document.createElement("<p style=\"color:"+colour+";\">");
            
        }catch(e){
            var p = document.createElement('p');
            p.setAttribute('style', "color:"+colour+";");
        } 
        //var text = document.createTextNode(message);
        p.innerHTML = message;
        div.appendChild(p);
    }
};

Utils.setOpacity = function (element, value){    
    if (value == 1){
        setStyle(element, { opacity: 
            (/Gecko/.test(navigator.userAgent) && !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 
                0.999999 : null });
                if(/MSIE/.test(navigator.userAgent))  
                    setStyle(element, {filter: getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'')});  
    } else {  
        if(value < 0.00001) value = 0;  
        setStyle(element, {opacity: value});
        if(/MSIE/.test(navigator.userAgent))  
            setStyle(element, 
            { filter: getStyle(element,'filter').replace(/alpha\([^\)]*\)/gi,'') +
              'alpha(opacity='+value*100+')' });  
    }   
};
Utils.setStyle = function (element, style) {
    for(k in style){
        element.style[k] = style[k];
    }
};
Utils.getStyle = function getStyle(element, name){
    return element.style[name];
};
Utils.setSelectedOption = function(selectElement, value){
    if(selectElement == null) return;
    if(selectElement['nodeName'] == null || selectElement['nodeName'].toLowerCase() != "select") return;
    var options = selectElement.options;
    var selected = false;
    var unselected = false;
    var i = 0; 
    while(!(selected && unselected) && i < options.length){
        if(options[i].value == value){
            options[i].selected = true;
            selected = true;
        }
        if(options[i].selected &&  options[i].value != value){
            options[i].selected = false; 
            unselected = true;
        }
        i++;
    }
    
};

Utils.newElement = function (element, attributes){
    var el;
    try{
        var att_string = "";
        if(attributes !=null){
            for(var i=0; i<attributes.length; i++){
                att_string += attributes[i].name+"=\""+attributes[i].value+"\" ";
            }
        }
        el = document.createElement("<"+element+" "+att_string+">");	
    }catch(e){
        el = document.createElement(element);
        if(attributes !=null){
            for(var i=0; i<attributes.length; i++){
                el.setAttribute(attributes[i].name, attributes[i].value);
            }
        }
    }
    return el;
};
Utils.findPos = function (obj) {
    
    var curleft = curtop = 0;
    
    if (obj.offsetParent) {
        curleft = obj.offsetLeft
        curtop = obj.offsetTop
        
        while (obj = obj.offsetParent) {
            curleft += obj.offsetLeft
            curtop += obj.offsetTop
        }
        
    }
    
    return [curleft,curtop];
};

Utils.removeChildren = function(element){
    
    while(element.hasChildNodes()){
        element.removeChild(element.firstChild);
    }
};
Utils.getElementsByClassNameRecurse = function(baseElement, className, elementList){
    var children = baseElement.childNodes;
    
    for(var i=0; i < children.length; i++){
        var child = children[i];
        if(!child) continue;
        if(child.tagName == "#text") continue;
        if(child.hasChildNodes()){
            elementList = Utils.getElementsByClassNameRecurse(child, className, elementList);
        }
        if(child.className != null && child.className == className){
            elementList.push(child);
        }
    }
    return elementList;
};
Utils.getElementsByClassName = function(baseElement, className){
    var elementList = new Array();
    return Utils.getElementsByClassNameRecurse(baseElement, className, elementList);
};

Utils.isInstance = function(obj, classType){
    if(obj==null || typeof(obj)!="object")return false;
    var constructorString = obj.constructor.toString();
    constructorString = constructorString.replace(/^function\s/, "");
    constructorString = constructorString.replace(/\([^)]*\)\s?\{(.|\n)*$/gm, "");
    constructorString = constructorString.replace(/\s/g, "");
    return (constructorString==classType);
};

Object.prototype.isInstance = function(classType){
    var constructorString = this.constructor.toString();
    constructorString = constructorString.replace(/^function\s/, "");
    constructorString = constructorString.replace(/\([^)]*\)\s?\{(.|\n)*$/gm, "");
    constructorString = constructorString.replace(/\s/g, "");
    return (constructorString==classType);
};
Utils.propLength = function(object){
    var count = 0;
    for(i in object){
        if(typeof(this[i]) == "function") continue;
        count++;
    }
    return count;
};

Utils.isChildOf= function (parent, child){
    var isChild = false;
    
    while((child)&&(child.nodeName != "BODY")){
        if(child == parent){	
            isChild = true;
            break;
        }
        child = child.parentNode;
    }
    
    return isChild;
};
Utils.setElementText = function(element, text){
    var textElementFound = false;
    var i =0;
    while(!textElementFound && i<element.childNodes.length){
        if(element.childNodes[i].nodeName.toLowerCase() == "#text"){
            element.childNodes[i].nodeValue = text;
            textElementFound = true;
        }
        i++;
    }
    
};   

Utils.getSelectedOptions = function(selectElement){
    var options = selectElement.options;
    var i = options.length-1;
    var selectedOptions = new Array();
    while(i >= 0){
        if(options[i].selected){
            selectedOptions[selectedOptions.length] = options[i];
        }
        i--;
    }
    return selectedOptions;
};
Utils.selectMoveOptions = function(selectElement, up){
    var finished = false;
    if(up){
        var i = 0;
        while(i< selectElement.options.length && !finished){
            if(i==0 && selectElement.options[i].selected){
                finished = true;
            }else if(i != 0 && selectElement.options[i].selected){
                var newOptions = Utils.arrayMoveElement(selectElement.options, selectElement.options[i], i-1);
                var x = 0;
                Utils.removeChildren(selectElement);
                while(x < newOptions.length){
                    selectElement.appendChild(newOptions[x]);
                    x++;
                }
            }
            i++;
        }
    }else{
        var i = selectElement.options.length-1 ;
        while(i>=0  && !finished){
            if(i==(selectElement.options.length-1) && selectElement.options[i].selected){
                finished = true;
            }else if(i != (selectElement.options.length-1) && selectElement.options[i].selected){
                var newOptions = Utils.arrayMoveElement(selectElement.options, selectElement.options[i], i+1);
                var x = 0;
                Utils.removeChildren(selectElement);
                while(x < newOptions.length){
                    selectElement.appendChild(newOptions[x]);
                    x++;
                }
            }
            i--;
        }
    }
};

Utils.getElementText = function(element){
    var i =element.childNodes.length-1;
    var textString = null;
    while(textString == null && i>=0){
        if(element.childNodes[i].nodeName.toLowerCase() == "#text"){
            textString = element.childNodes[i].nodeValue;
        }
        i--;
    }
    return textString;
    
};
Utils.arrayMoveElement = function(array, element, pos){
    var i = array.length-1;
    var origIndex = null;
    while(origIndex == null && i >= 0){
        if(array[i] == element){
            origIndex = i;
        }
        i--;
    }
    if(origIndex != null && pos != origIndex){
        array = Utils.arrayRemoveElement(array, element);
        array = Utils.arrayInsertElement(array, element, pos);
    }
    return array;
};


Utils.arrayInsertElement = function(array, element, pos){
    var arr = new Array(array.length+1);
    var i = 0;
    //alert("Array: "+array+"\nElement: "+element+"\npos:"+pos);
    if(pos >= array.length){
        while(i <= array.length-1){
            arr[i] = array[i];
            i++;
        }
        arr[array.length] = element;
    }else{
        while(i <= array.length-1){
            
            if(i<pos){
                arr[i] = array[i];
            }else if(i == pos){
                arr[i] = element;
                arr[i+1] = array[i];
            }else if(i > pos){
                arr[i+1] = array[i];
            }
            //alert("Inserting: "+arr);
            i++;
        }
    }
    return arr;
};
Utils.arrayRemoveElement = function(array, element){
    var i = array.length-1;
    var index = null;
    while(index == null && i >= 0){
        if(array[i] == element){
            index = i;
        }
        i--;
    }
    i = 0;
    var arr = new Array(array.length-1);
    while(i <= array.length-1){
        if(i<index){
            arr[i] = array[i];
        }else if(i > index){
            arr[i-1] = array[i];
        }
        i++;
    }
    return arr;
};
Utils.getMousePositionFromEvent = function(e){
    /*From QuirksBlog*/
    var posx = 0;
    var posy = 0;
    if (!e) var e = window.event;
    if (e.pageX || e.pageY){
        posx = e.pageX;
        posy = e.pageY;
    }else if (e.clientX || e.clientY){
        posx = e.clientX + document.body.scrollLeft
        + document.documentElement.scrollLeft;
        posy = e.clientY + document.body.scrollTop
        + document.documentElement.scrollTop;
    }
    return {'x':posx, 'y':posy};
}
HashMap.constructor = HashMap;

function HashMap(){
    this.mainMap = new Object();
    this.referenceMap = new Object();
    this.refCounter = 0;
}
HashMap.prototype.keyObjectToKey = function(keyObject){
    var ref= this.refCounter;
    this.referenceMap[ref] = keyObject;
    this.refCounter++;
    return ref;
};
HashMap.prototype.getRefFromKeyObject = function(keyObject){
    var ref = -1;
    for(i in this.referenceMap){
        var obj = this.referenceMap[i];
        
        if(obj == keyObject){
            ref = i;
            break;
        }    
    }
    
    return ref;
};

HashMap.prototype.add= function(keyObject, object){
    var ref = this.keyObjectToKey(keyObject);
    this.mainMap[ref] = object;
};
HashMap.prototype.get= function(keyObject){
    var ref = this.getRefFromKeyObject(keyObject);
    
    return this.mainMap[ref];
};
HashMap.prototype.size= function(){
    return this.refCounter;
};
HashMap.prototype.getByNum= function(i){
    return this.mainMap[i];
};

HashMap.prototype.debug= function(){
    for(i in this.mainMap){
        Utils.debug(i+" "+this.referenceMap[i]+" : "+this.mainMap[i])
    }
    
    return this.mainMap[i];
};

