﻿// This uses Marc's CSS and XHTML to create a drop down list
// with support for calling a function when an item is selected
// The dropdown is created like this:
//
// function myCallback(itemName) { alert("Selected: " + itemName); }
// var dd = new XangaDropdown('sortbyGroup', 'test', {def:"Default Option", test1:"Test One", test2:"Test Two"}, "def", myCallback);
//
XangaDropdown = function(rootEl, title, items, def, callback, emDef, defCssClass) {
    // Inner class for dropdown items
    XangaDropdownItem = function(parent, shortName, displayName) {
        var _parent = parent;
        var _shortName = shortName;
        var _displayName = displayName;
        var _linkEl = null;
        var _el = null;

        this.isCommand      = function() { return (_shortName.indexOf('cmd_') == 0); }
        this.getShortName   = function() { return _shortName; }
        this.getDisplayName = function() { return _displayName; }
        this.clicked        = function(evt) { _parent.selected(this,evt); }

        this.getElement = function() {
            if (_el == null) {
                _linkEl = null;
                if (_shortName == _parent.getDefault() && _parent.emDefault()) 
                    _linkEl = Builder.node('a', {href:"#", onclick:"return false;" }, [ Builder.node('em', {}, [ this.getDisplayName() ]) ]);
                else
                    _linkEl = Builder.node('a', {href:"#", onclick:"return false;" }, [ this.getDisplayName() ]);

                Event.observe(_linkEl, 'click', this.clicked.bindAsEventListener(this), false);
                
                if (_shortName == _parent.getDefault() && _parent.getDefaultCssClass() != null)
                    _el = Builder.node('li', {className:_parent.getDefaultCssClass()}, [ _linkEl ]);
                else
                    _el = Builder.node('li', {}, [ _linkEl ]);
            }
            return _el;
        }
        this.dispose = function() {
            Event.stopObserving(_linkEl, 'click', this.clicked.bind(this), false);
            Element.remove(_el);
            _el = null;
            _parent = null;
            _shortName = null;
            _displayname = null;
        }
    }
    
    var _rootEl = $(rootEl);
    var _title = title;
    var _def = def;
    var _defCss = defCssClass;
    var _callback = callback;
    var _emDef = (emDef == null) ? false : emDef;
    var _linkEl;
    var _listEl;
    var _options = new Array();
    var _blurrable = false;

    this.getDefault  = function() { return _def; }
    this.getLinkID   = function() { return _rootEl.id+"_lnk"; }
    this.linkclick   = function() { if (this.isExpanded()) this.hideList(); else this.showList(); }
    this.linkblur    = function() { if (_blurrable) this.hideList(); }
    this.unblurrable = function() { _blurrable = false; }
    this.blurrable   = function() { _blurrable = true; }
    this.isExpanded  = function() { return (_listEl.style.display == 'block'); }
    this.emDefault   = function() { return _emDef; }
    
    this.getDefaultCssClass = function()  { return _defCss; }
    this.setDefaultCssClass = function(c) { _defCss = c; }

    this.init = function(items) {
        Element.cleanWhitespace(rootEl);
        if (!Element.hasClassName(rootEl, 'selectmenu')) Element.addClassName(rootEl, 'selectmenu')

        _linkEl = Builder.node('a', {href:'#', className:'selectcurrent', onclick:'return false;'}, [ title + ":" ]);
        Event.observe(_linkEl, 'click',     this.linkclick.bind(this), false);
        Event.observe(_linkEl, 'blur',      this.linkblur.bind(this), false);
        Event.observe(_linkEl, 'mouseover', this.unblurrable.bind(this), false);
        Event.observe(_linkEl, 'mouseout',  this.blurrable.bind(this), false);
        _rootEl.appendChild(_linkEl);

        _listEl = Builder.node('ul', {className:'selectopts'});
        Event.observe(_listEl, 'mouseover', this.unblurrable.bind(this), false);
        Event.observe(_listEl, 'mouseout',  this.blurrable.bind(this), false);
        _rootEl.appendChild(_listEl);

        for (var shortName in items) this.addOption(shortName, items[shortName]);
    }
    this.selected = function(item, evt) {
        this.hideList();
        if (!item.isCommand()) this.setDisplayed(item);
        if (_callback != null) _callback(item.getShortName(), evt);
    }
    this.addOption = function(shortName, displayName) {
        var ddItem = new XangaDropdownItem(this, shortName, displayName);
        _listEl.appendChild(ddItem.getElement());
        if (shortName == _def) this.setDisplayed(ddItem);
        _options.push(ddItem);
    }
    this.showList = function() {
        _linkEl.parentNode.style.zIndex = 99999;
        _listEl.style.display = 'block';
        _linkEl.focus();
    }
    this.hideList = function() {
        _listEl.parentNode.style.zIndex = 10;
        _listEl.style.display = 'none';
    }
    this.setDisplayed = function(item) {
        if (_title == null || _title.length == 0)
            _linkEl.innerHTML = "<span><strong>" + item.getDisplayName() + "<strong></span>"
        else
            _linkEl.innerHTML = "<span>" + _title + ": <strong>" + item.getDisplayName() + "<strong></span>"
    }
    this.dispose = function() {
        // Dispose of all the drop down options
        for (var i = 0; i < _options.length; i++) _options[i].dispose();
        while (_options.length > 0) _options.pop();
        _options = null;

        // Remove from DOM
        Element.remove(_linkEl);
        Element.remove(_listEl);

        // Null out all variables
        _title = null;
        _items = null;
        _def = null;
        _callback = null;
        _linkEl = null;
        _listEl = null;
        _rootEl = null;
    }
    
    // now that all functions are defined, initialize the dropdown
    this.init(items);
}

XangaPrebuiltDropdown = function(linkEl, listEl, title, callback) {
	var _title = title;
	var _linkEl = $(linkEl);
	var _listEl = $(listEl);
	var _callback = callback;
	var _blurrable = true;
	
	this.linkclick   = function()    { if (this.isExpanded()) this.hideList(); else this.showList(); return false; }
	this.linkblur    = function()    { if (_blurrable) this.hideList(); return false; }
	this.unblurrable = function()    { _blurrable = false; }
	this.blurrable   = function()    { _blurrable = true; }
	this.isExpanded  = function()    { return (_listEl.style.display == 'block'); }
	this.getCallback = function()    { return _callback; }
	this.setCallback = function(cbk) { _callback = cbk; }
	
	this.init = function() {
		Element.cleanWhitespace(_linkEl);
		_linkEl.onclick = "return false;";
		Event.observe(_linkEl, 'click',     this.linkclick.bind(this), false);
		Event.observe(_linkEl, 'blur',      this.linkblur.bind(this), false);
        Event.observe(_linkEl, 'mouseover', this.unblurrable.bind(this), false);
        Event.observe(_linkEl, 'mouseout',  this.blurrable.bind(this), false);
		
		Element.cleanWhitespace(_listEl);
		Event.observe(_listEl, 'mouseover', this.unblurrable.bind(this), false);
		Event.observe(_listEl, 'mouseout',  this.blurrable.bind(this), false);
		
		
		var li = _listEl.firstChild;
		while (li != null) {
			li.firstChild.onclick = "return false;";
			Event.observe(li.firstChild, 'click', this.selected.bindAsEventListener(this), false);
			li = li.nextSibling;
		}
	}

    this.showList = function() {
        _linkEl.parentNode.style.zIndex = 99999;
        _listEl.style.display = 'block';
        _linkEl.focus();
    }
    this.hideList = function() {
        _listEl.parentNode.style.zIndex = 10;
        _listEl.style.display = 'none';
    }
	this.selected = function(e) {
		var text = Event.element(e).innerHTML;
		this.hideList();

		this.setSelected(text);
		
		return false;
	}
	this.setSelected = function(text) {
	    if (_title == null || _title.length == 0)
			_linkEl.innerHTML = "<span>" + text + "</span>";
		else
			_linkEl.innerHTML = "<span><strong>" + _title + ":</strong> " + text + "</span>";

		if (_callback != null) _callback(text);
	}
	this.dispose = function() {
	    // Remove from DOM
        Element.remove(_linkEl);
        Element.remove(_listEl);
        // Null out all variables
        _title = null;
        _linkEl = null;
        _listEl = null;
        _callback = null;
	}
	this.init();
}

XangaPanel = function(id, title, closeCbk) {
    var _id = id;
    var _title = title;
    var _closeCbk = closeCbk;
    var _panelEl;
    var _contentEl;
    var _closeEl;
    var _draggable;

    this.getContentID = function() { return _id + "_cntnt"; }
    this.getElement   = function() { return _panelEl; }
    this.close        = function() { _closeCbk(); }

    this.init = function() {
        _closeEl = Builder.node('a', {className:"close", href:"#", onclick:"return false;"}, [ "close" ]);
        Event.observe(_closeEl, 'click', this.close.bindAsEventListener(this), false);

        _contentEl = Builder.node('div', {className:"panelcontent"}, [ _closeEl ]);
        _panelEl = Builder.node('div', {className:"panel", id:_id}, [
            Builder.node('h2', {id:_id+"_h2"}, [
                Builder.node('span', null, [ _title ])
            ]),
            _contentEl
        ]);
    }

    this.insertContent = function(elArr) {
        for (var e = 0; e < elArr.length; e++)
            _contentEl.insertBefore(elArr[e], _closeEl);
    }

    this.clearContent = function() {
        var el = _contentEl.firstChild;
        while (el != null) {
            var next = el.nextSibling;
            _contentEl.removeChild(el);
            el = next;
        }
    }
    
    this.showCentered = function() {
        _panelEl.style.display = 'block';
        var elDims = Element.getDimensions( _panelEl );
        var x = ( document.body.clientWidth / 2 ) - ( elDims.width / 2 );
        var y = ( document.body.clientHeight / 2 ) - ( elDims.height / 2 );
        _panelEl.style.left = x + 'px';
        _panelEl.style.top = y + 'px';
        _draggable = new Draggable(_panelEl, {handle:_id+"_h2"});
    }
    this.showRelative = function(centerEl) {
        var x = this.getPosLeft(centerEl);
        var y = this.getPosTop(centerEl);
        _panelEl.style.display = 'block';
        _panelEl.style.left = x - 100 + 'px';
		_panelEl.style.top = y - 110 + 'px';
		_draggable = new Draggable(_panelEl, {handle:_id+"_h2"});
    }
    
    this.hide = function() {
        _panelEl.style.display = 'none';
    }

    this.getPosLeft = function(el) {
        var x = el.offsetLeft;
	    var tempEl = el.offsetParent;
	    while (tempEl != null) {
		    x += tempEl.offsetLeft;
		    tempEl = tempEl.offsetParent;
	    }
	    return x;
    }

    this.getPosTop = function(el) {
        var y = el.offsetTop;
	    var tempEl = el.offsetParent;
	    while (tempEl != null) {
		    y += tempEl.offsetTop;
		    tempEl = tempEl.offsetParent;
	    }
	    return y;
    }

    this.dispose = function() {
        // Destroy the draggable
        _draggable.destroy();
    
        // Remove from DOM
        Element.remove(_panelEl);
        
        // Unregister event listener
        Event.stopObserving(_closeEl, 'click', this.close.bindAsEventListener(this), false);
        
        // Set vars to null
        _id = null;
        _title = null;
        _closeCbk = null;
        _panelEl = null;
        _contentEl = null;
        _closeEl = null;
    }

    this.init();
}