/**
 *
 * @desc        FX Library (Height)
 * @author      Christopher Sanford
 * @version     1.0.0
 * @copyright   (CC) 2006 Christopher Sanford
 * @url         http://www.tdh-marketing.com/
 * @url         http://www.christophersanford.com/
 * 
 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 
 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 
 * any later version.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 
 * details.
 *
 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 
 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */
 
 
if (!Object.clone) {
    Object.prototype.clone = function()
    {
        var clone = new Object();
        if (typeof arguments.length != 'undefined') {
            var args = arguments;
            for (var t in this) {
                for (var a = 0, ac = args.length; a < ac; a++) {
                    if (t.toLowerCase() != args[a].toLowerCase()) {
                        clone[t] = this[t];
                    }
                }
            }
        } else {
            for (var t in this) {
                clone[t] = this[t];
            }
        }
        return clone;
    };
}

var GW = Class.create();
GW.prototype = {
	initialize: function() { return true; },
    nodeEmpty: function(node)
    {
        return !(/[^\t\n\r ]/.test(node.data));
    },
    nodeSkip: function(node)
    {
        return (node.nodeType == 8) || ((node.nodeType == 3) && this.nodeEmpty(node));
    },
    nextSibling: function(node)
    {
        while ((node = node.nextSibling)) {
            if (!this.nodeSkip(node)) return node;
        }
        return null;
    },
    previousSibling: function(node)
    {
        while ((node = node.previousSibling)) {
            if (!this.nodeSkip(node)) return node;
        }
        return null;
    },
    firstChild: function(node)
    {
        var child = node.firstChild;
        while (child) {
            if (!this.nodeSkip(child)) return child;
            child = child.nextSibling;
        }
        return null;
    },
    lastChild: function(node)
    {
        var child = node.lastChild;
        while (child) {
            if (!this.nodeSkip(child)) return child;
            child = child.previousSibling;
        }
        return null;
    }
};

GW.Cookies = {
	setCookie: function(name, value, days) {
		var expires = '';
		if (days) {
			var date = new Date();
			date.setTime(date.getTime() + (days*24*60*60*1000));
			expires = '; expires=' + date.toGMTString();
		}
		document.cookie = name + '=' + encodeURI(value) + '; ' + expires + '; path=/';
	},
	getCookie: function(name) {
        name = name.toLowerCase();
		var cookie = document.cookie.split(/;\s+/);
		for (var c = 0, cc = cookie.length; c < cc; c++) {
            cookie[c] = cookie[c].split('=');
            if (cookie[c][0].toLowerCase() == name) {
                return decodeURI(cookie[c][1]);
            }
		}
		return null;
	}
};

GW.Event = function() { return true; };
GW.Event.prototype = {
	initialize: function() { return true; },
	setEvent: function(obj, event, func)
	{
		var ref = null;
		if (typeof obj == 'string') {
			try {
				ref = eval(obj) ? obj+'.'+event : '$("'+ obj +'").'+event;
			} catch(e) {
				ref = '$("'+ obj +'").'+event;
			}
		} else if (typeof obj == 'object') {
			if (obj.id) {
				return this.setEvent(obj.id, event, func);
			} else {
				var id = this.getRandomId();
				while ($(id)) id = this.getRandomId();
				obj.id = id;
				return this.setEvent(id, event, func);
			}
		}
		try {
			var event = eval(ref);
			if (typeof event == 'function') {
				ref += ' = function(e) { event(e); func(e); }';
			} else {
				ref += ' = func;';
			}
			ref = eval(ref);
		} catch (e) { return null; }

		return (ref);
	},
	getRandomId: function()
	{
		return 'obj-'+Math.floor(Math.random()*1000);
	},
	getTarget: function(event)
	{
		event = (typeof event == 'undefined') ? window.event : event;
		var target = (event && typeof event.target == 'undefined') ? event.srcElement : event.target;
		if (target && target.nodeType == 3) target = target.parentNode;
		return (target) ? target : null;
	}
};

var FX = function() { return true; };
FX.prototype = {
	combo: false,
	timer: null,
	interval: 10,
	tween: 7,
	value: 0,
	sized: false,
	initialize: function(props) {
		this.extend(props || {});
		this.targ = (props.targ) ? $(props.targ) : $(props.trig);
		this.setValue(this.min);
		var obj = this;
		if (props.evt) {
			(new GW.Event()).setEvent(props.trig, props.evt, function(e) {
                obj.toggle();
                return false;
			});
		}
	},
    toggle: function()
    {
        //if (this.sized) return false;
        if (this.timer) return false;
        if (this.combo) {
		    if (this.timers()) return false;
			this.iterate();
        }
		this.sized = (this.sized) ? false : true;
        if (this.onStart) this.onStart();
		this.animate();
    },
	animate: function()
	{
		var value = this.getValue();
		if (this.timer) {
			if (value < this.value) {
			   value = Math.ceil(value+((this.value-value)/this.tween));
				this.setValue((value<this.value) ? value : this.value);
			} else if (value > this.value) {
				value = Math.floor(value-((value-this.value)/this.tween));
				this.setValue((value>this.value) ? value : this.value);
			} else {
				this.timer = clearInterval(this.timer);
                if (this.onStop) this.onStop();
				return;
			}
		} else {
			var value = this.getValue();
			this.value = (value < this.max) ?
						((this.max-this.min)+value) :
						((0-(this.max-this.min))+value);
			if (this.value < this.min) this.value = this.min;
			this.timer = setInterval(this.animate.bind(this), this.interval);
		}
	}
};

FX.Height = Class.create();
FX.Height.prototype = (new FX()).extend({
	attrib: 'height',
	getValue: function()
	{
		return parseInt(this.targ.style.height);
	},
	setValue: function(value)
	{
		this.targ.style.height = value+'px';
	}	
});

FX.Combo = Class.create();
FX.Combo.prototype = {
	initialize: function()
	{
		this.objects = new Array();
        var args = arguments;
		var objects =   (typeof args.length != 'undefined') ?
                        ((typeof args[args.length-1] == 'object') ?
					    args[args.length-1] :
					    null) :
					    null;
		if (!objects) return;
		if (typeof objects.length == 'undefined') objects = [objects];
		for (var o = 0, oc = objects.length; o < oc; o++) {
			objects[o].combo = true;
			var fx = new Array();
			for (var a = 0, ac = args.length-1; a < ac; a++) {
				objects[o].evt = (!a) ? objects[o].evt : null;
				switch (args[a].toLowerCase()) {
					case 'o':
					case 'opacity':
						fx.push(new FX.Opacity(objects[o]));
						break;
					case 'h':
					case 'height':
						fx.push(new FX.Height(objects[o]));
						break;
					case 'w':
					case 'width':
						fx.push(new FX.Width(objects[o]));
						break;
				}
			}
			this.objects.push(fx);
		}

        var clone = this.clone('toggle');
		for (var o = 0, c = this.objects.length; o < c; o++) {
			fx = this.objects[o];
			for (var f = 0, fc = fx.length; f < fc; f++) {
                fx[f].extend(clone);
            }
        }

	},
	iterate: function()
	{
		var fx = this.getThisFX();
		for (var f = 0, fc = fx.length; f < fc; f++) {
			if (fx[f] === this) continue;
			fx[f].sized = (fx[f].sized) ? false : true;
			fx[f].animate();
		}
        obj = fx;
		for (var o = 0, c = this.objects.length; o < c; o++) {
			if (this.objects[o] === obj) continue;
			fx = this.objects[o];
			for (var f = 0, fc = fx.length; f < fc; f++) {
				if (fx[f].timer) continue;
				if (fx[f].sized) {
					fx[f].sized = false;
					fx[f].animate();
				}
			}
		}
	},
	getThisFX: function()
	{
		for (var o = 0, oc = this.objects.length; o < oc; o++) {
			var fx = this.objects[o];
			for (var f = 0, fc = fx.length; f < fc; f++) {
				if (fx[f] === this) return fx;
			}
		}
		return null;
	},
	timers: function()
	{
		for (var o = 0, c = this.objects.length; o < c; o++) {
			var fx = this.objects[o];
			for (var f = 0, fc = fx.length; f < fc; f++) {
				if (fx[f] === this) continue;
				if (fx[f].timer) return true;
			}
		}
		return false;
	},
    toggle: function()
    {
        if (typeof arguments.length == 'undefined') return;
        var args = arguments;
		for (var o = 0, oc = this.objects.length; o < oc; o++) {
			var fx = this.objects[o];
            for (var f = 0, fc = fx.length; f < fc; f++) {
                fx[f].combo = false;
                for (var a = 0, ac = args.length; a < ac; a++) {
                    if (fx[f].attrib.toLowerCase() == args[a].toLowerCase()) fx[f].toggle();
                }
                fx[f].combo = true;
			}
		}
    }
};

(new GW.Event()).setEvent('window', 'onload', function() {

    // set curves for containers
    var objs = document.getElementsByClassName('container');
    var spans = ['tlc', 'trc', 'blc', 'brc'];
    for (var o = 0, c = objs.length; o < c; o++) {
        for (var s = 0, sc = spans.length; s < sc; s++) {
            var span = document.createElement('span');
            span.className = spans[s];
            objs[o].appendChild(span);
        }
        var height = parseInt(objs[o].offsetHeight);
        var width = parseInt(objs[o].offsetWidth);
        if(height%2 != 0) height++;
        if(width%2 != 0) width++;
        objs[o].style.height = height+'px';
        objs[o].style.width = width+'px';
    }

    var objs = [];
    var dom = new GW();
    var nav = $('nav');
    if (!nav) return;

    var wrap = $('nav-wrap');
    var curves = ['nav-top', 'nav-bot'];

    wrap.style.visibility = 'hidden';

    for (var c = 0, cc = curves.length; c < cc; c++) {
        var span = document.createElement('span');
        span.className = curves[c];
        switch (curves[c]) {
            case 'nav-top':
                wrap.insertBefore(span, nav);
                break;
            case 'nav-bot':
                wrap.appendChild(span);
                break;
        }
    }

    var nodes = nav.getElementsByTagName('LI');
    for (var n = 0, c = nodes.length; n < c; n++) {
        var ank = dom.firstChild(nodes[n]);
        var div = dom.nextSibling(ank);
        var list = nodes[n].getElementsByTagName('UL');
        if (!list.length) continue;
        if (ank && div) {
            objs.push({
                trig: ank,
                targ: nodes[n],
                max: div.offsetHeight+ank.offsetHeight,
                min: ank.offsetHeight,
                evt: 'onclick',
                interval: 1,
                tween: 1,
                onStart: function()
                {
                    var trig = (this.sized) ? this.trig.id : null;
                    GW.Cookies.setCookie('nav-exp', trig);
                }
            });
        }
    }

    var fx = new FX.Combo('h', objs);
    var cookie = GW.Cookies.getCookie('nav-exp');
    for (var o = 0, c = fx.objects.length; o < c; o++) {
        if (fx.objects[o][0].trig.id == cookie) {
            fx.objects[o][0].toggle();
        }
    }

    setTimeout(function() {
        wrap.style.visibility = 'visible';
        for (var o = 0, c = fx.objects.length; o < c; o++) {
            fx.objects[o][0].interval = 5;
            fx.objects[o][0].tween = 3;
        }
    }, 100);

});