﻿var SelectControl = Class.create({
    initialize: function(select, options) {
        var elementId = $(select).id;

        this.viewElement = new Element("div", { id: elementId + "_view" }).addClassName('selectControlLabel');
        this.valueElement = new Element("input", { name: $(select).name, type: 'hidden', id: elementId + "_value" });
        new Insertion.Before(select, this.viewElement);
        new Insertion.Before(select, this.valueElement);

        $(this.viewElement.parentNode).setStyle({ 'position': 'relative' });

        //var selectPos = this.viewElement.cumulativeOffset();
        //var selectWidth = this.viewElement.getWidth();
        var listMouseover = function(e) {
            this.listActive = 1;
        };
        var listMouseout = function(e) {
            this.listActive = 0;
            this.hideTimeoutKey = setTimeout(this.timeoutHide.bind(this), 1500);
        };
        this.selectList = new Element("ul")
                            .addClassName('selectControlList')
                            ; //.observe('mouseover', listMouseover.bind(this))
        //.observe('mouseout', listMouseout.bind(this));

        // apply positioning
        this.update = new Element('div').insert(this.selectList).setStyle({ position: 'absolute', width: this.viewElement.getWidth() + 'px' });
        setTimeout(this.setPosition.bind(this), 20);

        // don't get in the way of other selectors
        this.sendToBack(); 
        
        this.options = options;
        this.optionalData = {};
        this.data = {};
        this.select = select;
        this.selectOptions = [];

        var optionList = $(this.select).getElementsByTagName('option');
        var nodes = $A(optionList);
        for (i = 0; i < nodes.length; i++) {
            this.data[nodes[i].value] = nodes[i].innerHTML;
        }

        // hide initial select box
        $(this.select).hide();

        //Event.observe(this.element, "click", this.activate.bindAsEventListener(this));
    },
    setPosition: function() {
        new Insertion.Before(this.select, this.update);
        Position.clone(this.viewElement, this.update, {
            setHeight: false,
            offsetTop: this.viewElement.offsetHeight + (this.options.offsetListTop || 0),
            offsetLeft: (this.options.offsetListLeft || 0)
        });
        this.update.hide();
    },
    start: function() {

        var optionList = $(this.select).getElementsByTagName('option');
        var nodes = $A(optionList);
        for (i = 0; i < nodes.length; i++) {
            this.selectList.insert(
                    new Element("li", { id: nodes[i].value, title: nodes[i].title })
                      .update(this.writeLabel(nodes[i].value))
                      .observe('mouseover', function() { $(this).addClassName("active"); })
                      .observe('mouseout', function() { $(this).removeClassName("active"); })
                      .observe('click', this.updateLabel.bindAsEventListener(this, nodes[i].value))
                );
            if (i == 0 || nodes[i].getAttribute("selected")) {
                this.viewElement.update(this.writeLabel(nodes[i].value));
                this.valueElement.value = nodes[i].value;
            }
        }
        if (nodes.length > 1) {
            this.viewElement.observe("click", this.showList.bindAsEventListener(this));
        } else {
            this.viewElement.addClassName('inactiveSelectControlLabel');
        }
    },
    resetSelected: function(key) {
        this.selectList.select('li').each(function(el) {
            el.removeClassName('selected');
            if (el.id == key)
                el.addClassName('selected');
        });
    },
    writeLabel: function(key) {
        return new Element('span').insert(this.data[key]);
    },
    sendToBack: function() {
        this.update.setStyle({ zIndex: '500' });
        $(this.viewElement.parentNode).setStyle({ 'zIndex': '499' });
    },
    bringToFront: function() {
        this.update.setStyle({ zIndex: '600' });
        $(this.viewElement.parentNode).setStyle({ 'zIndex': '499' });
        //$(this.viewElement.parentNode).setStyle({ 'zIndex': '599' });
    },
    hideList: function(options) {
        var duration = 0.35;
        if (options && options.duration) {
            duration = options.duration;
        }
        this.fade = Effect.Fade(this.update, { duration: duration });
        this.sendToBack();
        this.userWantsList = 0;
    },
    showList: function(e, options) {
        this.appear = Effect.Appear(this.update, { duration: 0.35 });
        this.bringToFront();
        //this.hideTimeoutKey = setTimeout(this.timeoutHide.bind(this), 1500);
        this.userWantsList = 1;
        var foo = function(e) {
            var elt = $(Event.element(e));
            if (!elt.descendantOf(this.viewElement.parentNode)) {
                this.hideList();
            }
        };
        Event.observe(document, 'click', foo.bind(this));
    },
    timeoutHide: function() {
        if (!this.userWantsList) return;
        if (!this.listActive) this.hideList();
    },
    updateLabel: function(e, key) {
        this.updateLabelBase(e, key);
    },
    updateLabelBase: function(e, key) {
        var label = this.data[key];
        this.viewElement.update(this.writeLabel(key));
        this.valueElement.value = key;
        this.resetSelected(key);
        this.hideList();
    }
});

