/**
 * @name: dd.js
 * @description: customize dropdown 
 * @author: Marghoob Suleman - http://www.marghoobsuleman.com/
 * @version: 1.5 
 * @date: March 09, 2009
 * @released: March 31, 2009 {1.4}, March 30, 2009 {1.3}, March 22, 2009 {1.2}, March 20, 2009 {1.0}
 * @category: Javascript Custom Component
 * @copyright (c) 2009 Marghoob Suleman (powered by: http://www.giftlelo.com/)
 */

MSDropDown = {
    settings: {
        theme:'blue', //will use later
        autoHide:'off', //will use later
        offClass:'aOff',
        onClass:'aOn',
        maintainHeight:0,//will use later
        idpostfixmain:'_ms',
        idpostfixchild:'_child',
        idpostfixa:'_msa',
        idposttitlediv: '_divtitle',
        idposttitle: '_title',
        idhidden: '_input',
        showTitle:true,
        visibleRows:7, //will use later
        iconWithTitle:true
    },
    styles: {
        ddclass:'msDropDown',
        childclass:'msDropDown_Child',
        arrow: 'msdropdown/dd_arrow.gif',
        arrowclass: 'msArrow',
        titleclass: 'msDropdownTitle',
        disabled:'msDisabled',
        enabled:'msEnabled'
    },
    attributes: {
        action:"onfocus,onblur,onchange,onclick,ondblclick,onmousedown,onmouseup,onmouseover,onmousemove,onmouseout,onkeypress,onkeydown,onkeyup",
        prop:"size,multiple,disabled,tabindex"
    },
    selected: new Object(),
    zIndex:999,
    insideWindow:false,
    dp_array:new Object(),
    currentDiv:'',
    init: function(byID) {
        //this.selected = new Object();
        //this.dp_array = new Object();
        //make cutomdropdowns
        this.storeNmake(byID);
    },
    storeNmake: function(byID) {
        //storing datas
        var dps = this.getAllDropDown(byID);
        var total = dps.length;
        for(var iCount=0;iCount<total;iCount++) {
            var currentSelect = dps[iCount];
            if(currentSelect.id!=undefined && currentSelect.id.length>0) {
                //adding a custome event to refresh dropdown
                this.addNewEvents(currentSelect.id);
                var prop = new Array();
                var selectProp = this.getSelectProperties(currentSelect.id);
                prop["selectAttributes"] = selectProp.attributes;
                prop["selectAction"] = selectProp.action;
                //format dropdown
                var width = (this.dp_array[currentSelect.id]==undefined) ? $(currentSelect).width() : this.dp_array[currentSelect.id].width;
                var height = (this.dp_array[currentSelect.id]==undefined) ? $(currentSelect).height() : this.dp_array[currentSelect.id].height;
                $(currentSelect).css({
                    width:width+'px'
                });
                var oOptions = $("#"+currentSelect.id +"> *");
                var totalOptions = oOptions.length;
                //internal counter
                for(var optionCount=0;optionCount<totalOptions;optionCount++) {
                    var foundopt = false;
                    if(oOptions[optionCount].nodeName=="OPTION") {
                        var currentOption = oOptions[optionCount];
                        var values = this.getOptionsProperties(currentOption);
                        prop.push(values);
                    } else if(oOptions[optionCount].nodeName=="OPTGROUP") {
                        foundopt = true;
                        var optinit = false;
                        var oCurrentOptGroup = oOptions[optionCount].childNodes;
                        for(var optoptioncount=0;optoptioncount<oCurrentOptGroup.length;optoptioncount++) {
                            var _currentOption = oCurrentOptGroup[optoptioncount];
                            var _values = this.getOptionsProperties(_currentOption);
                            if(_values!=false) {
                                if(optinit==false) {
                                    optinit = true;
                                    var opt = this.getOptGroupProperties(oOptions[optionCount]);
                                    _values["optstart"] = opt;
                                }
                                prop.push(_values);
                            }
                        }
                        if(foundopt) {
                            //var last
                            prop[prop.length-1].optend = "end";
                        }
							   
                    }
                }
                prop["id"] = currentSelect.id;
                prop["position"]= (this.dp_array[currentSelect.id]==undefined) ? $("#"+currentSelect.id).position() : this.dp_array[currentSelect.id].position;
                prop["width"]= width;
                prop["height"]= height;
                //store
                this.store(currentSelect.id, prop);
            } else {
                throw "An id is required!";
            }
        }
        //Make
        this.makeAdropDown(byID);
    },
    setOutOfVision: function(id) {
        $("#"+id).css({
            position:'absolute',
            left:'-5000px',
            top:'-5000px'
        });
    },
    makeAdropDown: function() {
        var alldps = this.getdps();
        var idMain = this.settings.idpostfixmain;
        var idChild = this.settings.idpostfixchild;
        var idhidden = this.settings.idhidden;
        var idA = this.settings.idpostfixa;
        var idtitlediv = this.settings.idposttitlediv;
        var idtitle = this.settings.idposttitle;
        var ddclass = this.styles.ddclass;
        var childclass = this.styles.childclass;
        var arrowclass = this.styles.arrowclass;
        var arrow = this.styles.arrow;
        var titleclass = this.styles.titleclass;
        var counter = 0;

        for(i in alldps) {
            var id = i;
            //hide original dropdown
            this.setOutOfVision(id);
			
            var values = alldps[i];
            var selectProp = values["selectAttributes"];
            var selectAction = values["selectAction"];
            //make a dropdown
            var position = values.position;
            var width = (values.width)+ 'px';
            var titlewidth = values.width  - 18 + 'px';
            var top = position.top + 'px'; //remove 100 when finalize
            var left = position.left + 'px';
            var dd_id = id+idMain; //+counter;
            if($("#"+dd_id).length>0)  {
                $("#"+dd_id).remove();
            }
            var childid = dd_id+idChild;
            var childtitledivid = dd_id+idtitlediv;
            var titleid = dd_id+idtitle;
            var hiddeninput = dd_id+idhidden;
            var onchange = values.onchange;
            //alert(onchange)
            //make main holder //
            var childheight = '';
            //alert("values.length " + values.length)
            if(values.length>this.getVisibleRows()) childheight = '200';
            var ddhtml = "";
            var zIndex = this.zIndex--;
            var css = (selectProp["disabled"]==true) ? " " + this.styles.disabled : this.styles.enabled;
            ddhtml += "<div  id='"+dd_id+"' class='"+ddclass+"' style='position:relative;width:"+width+";z-Index:"+zIndex+"'>"; //main div
            if(selectProp["disabled"]==true) {
                ddhtml += "<div id='"+childtitledivid+"' class='"+css+"'><div class='"+arrowclass+"'><img src='"+arrow+"' border='0' align='right' /></div><div style='white-space:nowrap;width:"+titlewidth+"' class='"+titleclass+"' id='"+titleid+"'>Loading...</div><input style='text-indent:-400px;position:absolute; top:0; left:0; border:none; background:transparent;cursor:pointer;width:0px;heigh:0px;' type='text' value='' id='"+hiddeninput+"' name='"+hiddeninput+"' /></div>";//title div
            } else {
                ddhtml += "<div id='"+childtitledivid+"' class='"+css+"' onclick=\"MSDropDown.openDropDown('"+dd_id+"')\"><div class='"+arrowclass+"'><img src='"+arrow+"' border='0' align='right' /></div><div style='white-space:nowrap;width:"+titlewidth+"' class='"+titleclass+"' id='"+titleid+"'>Loading...</div><input style='position:absolute; top:0; left:0; border:none; background:transparent;cursor:pointer;width:0px;heigh:0px;' type='text' value='' id='"+hiddeninput+"' name='"+hiddeninput+"' /></div>";//title div
            }
            ddhtml += "<div id='"+childid+"' class='coloredScroll "+childclass+"' style='width:"+(values.width+2)+"px'>"; //child div
            var ahtml = "";
            //create a tag
            var sValue = "";
            var sImg = "";
            for(var aCount=0;aCount<values.length;aCount++) {
                var curretna = values[aCount];
                var aID = dd_id+"_a_"+aCount;
                var value = curretna.value;
                if(aCount==0){
                    var selectedID =  aID;
                }
                var text = curretna.text;
                var selected = curretna.selected;
                var icon = curretna.icon;
                //get selected text
                if($("#"+id+" option:selected").text()==text) {
                    sValue = text;
                    selectedID = aID;
                    var showIcon = this.getSetting("iconWithTitle");
                    if(icon != undefined && showIcon==true) {
                        sImg = "<img hspace='2' align='absMiddle' src='"+icon+"' />";
                    }
                }
                var isDisabled = curretna.disabled;
                var img = "";
                var sTitle = (this.getShowTitle() == true) ? text : '';
                var innerStyle = (curretna.style!=undefined) ? curretna.style : '';
                if(curretna.optstart != undefined) {
                    var optLabel = (curretna.optstart.label==undefined) ? '' : curretna.optstart.label;
                    ahtml += "<div style='display:block;clear:both;'><span style='font-weight:bold;font-style:italic'>"+optLabel+"</span><div style='display:block;text-indent:10px;clear:both:'>";
                }
                if(icon != undefined) {
                    img = "<img id='"+aID+"_icon' class='icon' align='left' src='"+icon+"' />";
                }
                if(isDisabled == undefined || isDisabled==false) {
                    ahtml += "<a id='"+aID+"' title='"+sTitle+"' style='display:block;"+innerStyle+"'+ href='javascript:void(0);' value='"+(value)+"' onclick=\"MSDropDown.setSelected('"+dd_id+"', '"+text+"', '"+aID+"', '"+value+"', '"+icon+"')\">";//a tag start
                } else {
                    ahtml += "<a id='"+aID+"' title='"+sTitle+"' style='cursor:pointer;filter:alpha(opacity=50);-moz-opacity:.50;opacity:.50;display:block;"+innerStyle+"' href='javascript:void(0);' value='"+(value)+"'>";//a tag start
                }
                ahtml += img + '<span>'+text+"</span></a>";//a tag end
                if(curretna.optend == "end") {
                    ahtml += "</div></div>"; //opt group end
                }
            //ahtml += "<a id='"+aID+"' title='"+sTitle+"' style='display:block' href=\"javascript:void(0);MSDropDown.setSelected('"+dd_id+"','"+text+"','"+aID+"')\">"+img + '<span>'+text+"</span></a>" //a tag
            }
            sValue = (sValue=='') ? values[0].text : sValue;
            ddhtml += ahtml;
            ddhtml += "</div>"; //child div end
            ddhtml += "</div>" //main div end
            counter++;
            $("#" + id).after(ddhtml);
            //deafult opening
            if(selectProp["disabled"]==false) {
            //will do something
            } else {
                $("#"+dd_id).css({
                    opacity:0.4
                });
            }
            //apply events
            this.applyEvents(dd_id, values, id);
            if(childheight!='') $("#"+childid).css({
                overflowY:'scroll',
                overflowX:'hidden',
                height:childheight+'px'
            });
            //selected
            $("#"+titleid).html(sImg+sValue);
            this.manageSelection(id, selectedID);
        //i m not using this now;
        //this.setOutOfVision(hiddeninput);
        }
		
    },
    hasAction: function(prop, action) {
        var sAction = action;
        var selectAction = prop;
        for(var i in selectAction) {
            if(i.toString().toLowerCase()==sAction.toString().toLowerCase() && selectAction[i]==true) {
                return true;
            }
        }
        return false;
    },
    applyEvents: function(id, values, parent) {
        var sID = id;
        var parent_id = parent;
        var props = values;
        var selectProp = props["selectAttributes"];
        var selectAction = props["selectAction"];
        if(selectProp["disabled"]==false) {
            for(var i in selectAction) {
                if(selectAction[i]==true) {
                    switch(i) {
                        case 'onfocus':
                            $("#"+sID).bind("focus", function(e) {
                                $("#"+parent_id).focus();
                            });
                            break;
                        case 'onblur':
                            //has somewhere else;
                            break;
                        case 'onchange':
                            //has somewhere else;
                            break;
                        case 'onclick':
                            $("#"+sID).bind("click", function(e) {
                                $("#"+parent_id).click();
                            });
                            break;
                        case 'ondblclick':
                            $("#"+sID).bind("dblclick", function(e) {
                                $("#"+parent_id).dblclick();
                            });
                            break;
                        case 'onmousedown':
                            $("#"+sID).bind("mousedown", function(e) {
                                $("#"+parent_id).mousedown();
                            });
                            break;
                        case 'onmouseup':
                            $("#"+sID).bind("mouseup", function(e) {
                                $("#"+parent_id).mouseup();
                            });
                            break;
                        case 'onmouseover':
                            $("#"+sID).bind("mouseover", function(e) {
                                $("#"+parent_id).mouseover();
                            });
                            break;
                        case 'onmousemove':
                            $("#"+sID).bind("mousemove", function(e) {
                                $("#"+parent_id).mousemove();
                            });
                            break;
                        case 'onmouseout':
                            $("#"+sID).bind("mouseleave", function(e) {
                                $("#"+parent_id).mouseout();
                            });
                            break;
                        case 'onkeypress':
                            $("#"+sID).bind("keypress", function(e) {
                                $("#"+parent_id).keypress();
                            });
                            break;
                        case 'onkeydown':
                            $("#"+sID).bind("keydown", function(e) {
                                $("#"+parent_id).keydown();
                            });
                            break;
                        case 'onkeyup':
                            $("#"+sID).bind("keyup", function(e) {
                                $("#"+parent_id).keyup();
                            });
                            break;
                    }
                }
            }
        }
    },
    addNewEvents: function(id) {
        document.getElementById(id).refresh = function(e) {
            MSDropDown.refresh(this.id);
        }
    },
    refresh: function(id) {
        MSDropDown.storeNmake("#"+id);
    },
    manageSelection: function(id, selected) {
        if(this.selected[id]==undefined) {
            this.selected[id] = {
                selected:selected,
                previous:selected
            };
        }
        this.selected[id].selected = selected;
        if(this.selected[id].previous != this.selected[id].selected) {
            $("#"+ this.selected[id].previous).removeClass('selected');
        }
        $("#"+ this.selected[id].selected).addClass('selected');
        this.selected[id].previous = this.selected[id].selected;
    },
    /**** manage selection ***/
    setSelected: function(id, value, aID, val, imgsrc) {
        var parentID = id.split("_")[0];
        this.selected[parentID].current = aID;
        var sID = id;
        var oPorop = prop;
        var targetDiv = sID+this.settings.idposttitle;//"_title";
        var hiddeninput = sID+this.settings.idhidden;
        var prop = this.getdps(parentID);

        $("#"+parentID + " option:selected").text(value.toString());
        //working here... (problem in ie if value is not defined)
        $("#"+parentID + " option:selected").val(val.toString());
        //check if there is any method;
        if($("#"+parentID).attr("onfocus")!=undefined) {
            $("#"+parentID).focus();
            $("#"+hiddeninput).focus();
        }
        if($("#"+parentID).attr("onchange")!=undefined) {
            $("#"+parentID).change();
        }
        $("#"+hiddeninput).val(value);
        var showIcon = this.getSetting("iconWithTitle");
        if(imgsrc.toString()!='undefined' && showIcon==true) {
            value = "<img hspace='2' align='absmiddle' src='"+imgsrc+"' />"+ value;
        }
        $("#"+targetDiv).html(value);
        this.manageSelection(parentID, aID);
        //alert(this.selected[parentID].current);
        this.closeDropDown();
    },
    openDropDown: function(id) {
        //$("#city").text = "Delhi";
        var prentDiv = id;
        var childDiv = id+="_child";
        if($("#"+childDiv).css("display")=="block") {
            MSDropDown.closeDropDown();
            return false;
        }
        var position = $("#"+prentDiv).position();
        var childPosTop = $("#"+prentDiv).height() + parseInt($("#"+prentDiv).css("padding-top")) + 'px';
        var parentWidth = parseInt($("#"+prentDiv).width());
        var childWidth = parseInt($("#"+childDiv).width());
        if(childWidth  < parentWidth) {
            $("#"+childDiv).css({
                width:$("#"+prentDiv).width()+'px'
            });
        }
        this.currentDiv = childDiv;
        $("#"+childDiv).css({
            position:'absolute',
            top:childPosTop,
            left:'-1px'
        });
        $("#"+childDiv).slideDown("fast");
        //$("#"+childDiv).show("fast");
        $("#"+childDiv).mouseover(function(e) {
            MSDropDown.setInsideWindow(true);
        });
        $("#"+childDiv).mouseout(function(e) {
            MSDropDown.setInsideWindow(false);
        });
        $(document).bind('mouseup', function(e) {
            if(MSDropDown.insideWindow==false) {
                $(document).unbind('mouseup');
                MSDropDown.closeDropDown();
            }
        });
        return true;
    },
    setInsideWindow: function(set) {
        this.insideWindow = set;
    },
    closeDropDown: function() {
        var curerntDiv = this.currentDiv;
        var parentID = curerntDiv.split("_")[0];
        var hiddeninput = curerntDiv+this.settings.idhidden;
        if($("#"+parentID).attr("onblur")!=undefined) {
            $("#"+parentID).focus();
            $("#"+hiddeninput).focus();
        }
        $("#"+this.currentDiv).slideUp("fast");
    },
    /* getter setter */
    store: function(id, prop) {
        this.dp_array[id] = prop;
    },
    getdps: function(byID) {
        return (byID==undefined) ? this.dp_array : this.dp_array[byID];
    },
    getAllDropDown: function(byID) {
        return (byID==undefined) ? $("body select") : $(byID);
    },
    showTitle: function(show) {
        this.settings.showTitle = show;
    },
    getShowTitle: function() {
        return this.settings.showTitle;
    },
    setVisibleRows: function(rows) {
        this.settings.visibleRows = rows;
    },
    getVisibleRows: function() {
        return this.settings.visibleRows;
    },
    getSelectProperties: function(id) {
        var currentSelect = id;
        var attributes = this.attributes.prop;
        var prop = new Object();
        //attributes
        var attribs = attributes.split(",");
        var total = attribs.length;
        prop.attributes = new Object();
        for(var iCount=0;iCount<total;iCount++) {
            var key = attribs[iCount].toString();
            var value = $("#"+currentSelect).attr(key);
            if(value!=undefined) {
                prop.attributes[key] = value;
            }
        }
        //actions
        attributes = this.attributes.action;
        attribs = attributes.split(",");
        total = attribs.length;
        prop.action = new Object();
        for(var i=0;i<total;i++) {
            var _key = attribs[i].toString();
            var _value = $("#"+currentSelect).attr(_key);
            if(_value!=undefined) {
                prop.action[_key] = true;
            } else {
                prop.action[_key] = false;
            }
        }
        return prop;
    },
    getOptionsProperties: function(option) {
        //returns : options, selected, icons
        var currentOption = option;
        if(currentOption.text!=undefined) {
            var prop = new Object();
            prop["text"] = currentOption.text;
            prop["value"] = (currentOption.value==undefined) ? currentOption.text : currentOption.value;
            var attribs = currentOption.attributes;
            var total = attribs.length;
            for(var iCount=0;iCount<total;iCount++) {
                var att = attribs[iCount];
                prop[att.nodeName] = att.nodeValue;
            }
            return prop;
        } else {
            return false;
        }
    },
    getOptGroupProperties: function(opt) {
        var oOpt = opt;
        var prop = new Object();
        prop["optstart"] = "start";
        var attribs = oOpt.attributes;
        var total = attribs.length;
        if(total>0) {
            for(var iCount=0;iCount<total;iCount++) {
                var att = attribs[iCount];
                prop[att.nodeName] = att.nodeValue;
            }
        }
        return prop;
    },
    showIconWithTitle: function(show) {
        this.settings.iconWithTitle = show;
    },
    getSetting: function(prop) {
        return this.settings[prop];
    }
}

//how to call
/*
$(document).ready(function(e) {
							try {
								MSDropDown.init();
							} catch(e) {
								alert(e);
							}
						   }
				  )
*/
