Fibonacci.INSTANCE = null;
Fibonacci.getInstance = function() {
    if (!Fibonacci.INSTANCE) {
        Fibonacci.INSTANCE = new Fibonacci();
    }
    
    return Fibonacci.INSTANCE;
}
function Fibonacci(first, second) {
    this.first = (first)? first : 1;
    this.second = (second)? second : 1;
    
    this.storage = new Object();
}
Fibonacci.prototype.getAtPlace = function(place) {
    if (this.storage[place]) {
        return this.storage[place];
    } else {
        if (place > 1) {
            var result = this.getAtPlace(place - 1) + this.getAtPlace(place - 2);
            this.storage[place] = result;
            return result;
        } else if (place == 1) {
            return this.second;
        } else if (place == 0) {
            return this.first;
        }
    }
}
Fibonacci.prototype.findNearestIndex = function(value) {
    var offset = 0;
    while (this.getAtPlace(++offset) <= value);

    return offset;
}
Fibonacci.GET_NEXT = function(value) {
	var fibonacciObject = Fibonacci.getInstance();
	return fibonacciObject.getAtPlace(fibonacciObject.findNearestIndex(value));
	//return value + 25;
}
Fibonacci.GET_PREV = function(value) {
	var fibonacciObject = Fibonacci.getInstance();
	return fibonacciObject.getAtPlace(fibonacciObject.findNearestIndex(value) - 2);
	//return (value - 25 < 0)? 0 : value - 25;
}

function AccordeonObject(field, button) {
	this.field = field;
	this.button = button;
	
	this.field.style.overflow = "hidden";
	if (!this.field.style.height) {
	   this.field.style.height = this.field.scrollHeight + "px";
	}
}

Accordeon.EXPAND_INTERVAL = 10;
Accordeon.COLLAPSE_INTERVAL = 10;
Accordeon.OPERATION_INTERVAL = 10;
Accordeon.BOUNCE_INTERVAL = 50;
Accordeon.BOUNCE_DISTANCE = 5;
Accordeon.ASYNC = true;
Accordeon.MIN_ELEMENT_HEIGHT = 1;
function Accordeon() {
	this.collection = null;
	this.openedField = null;
	
	this.expandWaiter = null;
	this.collapseWaiter = null;
	
	this.operationWaiter = null;
	this.operationInProgress = false;
    
    this.bounceWaiter = null;
    this.bounceLoops = 0;
	
	this.init();
}
Accordeon.prototype.initFieldPair = function(field, link) {
	this.collection.push(
		new AccordeonObject(
			field,
			link
		)
	);
	this._initBox(this.collection.length - 1);
	
	if (parseInt(field.style.height) != Accordeon.MIN_ELEMENT_HEIGHT) {
	    if (!this.openedField) {
	        this.openedField = this.collection.length - 1;
	    } else {
	        field.style.height = Accordeon.MIN_ELEMENT_HEIGHT + "px";
	    }
	}
}
Accordeon.prototype.init = function() {
	this.collection = new Array();
}
Accordeon.prototype._initBox = function(index) {
	var obj = this;
	this.collection[index].button.onclick = function() {
		obj._handleButtonOnClick(index);
	}
}
Accordeon.prototype._handleButtonOnClick = function(index) {
    if (!this.operationInProgress) {
        this._close(this.openedField);
		
		var needToOpen = parseInt(this.collection[index].field.style.height) == Accordeon.MIN_ELEMENT_HEIGHT;
		
		if (needToOpen && this.openedField != index) {
			var obj = this;
			var operatingWaiting = setInterval(function() {
				if (Accordeon.ASYNC || !obj.operationInProgress) {
					obj.openedField = null;
					if (index != null) {
						obj._open(index);
						obj.openedField = index;
					}
					
					clearInterval(operatingWaiting);
				}
			}, Accordeon.OPERATION_INTERVAL);
		} else if (!needToOpen) {
		    this._close(index); 
		} else {
			this.openedField = null;
		}
	}
}
Accordeon.prototype._bounce = function(index) {
    this.bounceLoops = 0;
    var obj = this;
    
    this.bounceWaiter = setInterval(function() {
        if (obj.bounceLoops >= 1) {
            obj._finishOpenProcess(index);
            clearInterval(obj.bounceWaiter);
        } else {
            obj.collection[index].field.style.height = (parseInt(obj.collection[index].field.style.height) - Accordeon.BOUNCE_DISTANCE) + "px";
            obj.bounceLoops++;
        }
    }, Accordeon.BOUNCE_INTERVAL);
}
Accordeon.prototype._finishOpenProcess = function(index) {
    var scrollHeight = parseInt(this.collection[index].field.scrollHeight);
    this.collection[index].field.style.height = scrollHeight + "px";
    this.operationInProgress = false;
}
Accordeon.prototype._open = function(index) {
	if (index != null) {
		this.operationInProgress = true;
		
		clearInterval(this.expandWaiter);

		var obj = this;
		var someTimeForIEToStart = setInterval(function () {
			obj.collection[index].field.style.visibility = "visible";
			var scrollHeight = parseInt(obj.collection[index].field.scrollHeight);
			
			
			obj.expandWaiter = setInterval(function() {
				if (parseInt(obj.collection[index].field.style.height) < scrollHeight) {
				    var newHeight = Fibonacci.GET_NEXT(parseInt(obj.collection[index].field.style.height));
				    newHeight = (newHeight > scrollHeight)? scrollHeight : newHeight 
					obj.collection[index].field.style.height = newHeight + "px";
				} else {
                    obj._bounce(index);
                    Cookies.instance().setCookie("menuCategory", obj.collection[index].field.id);
                    clearInterval(obj.expandWaiter);
				}
			}, Accordeon.EXPAND_INTERVAL);
			
			clearInterval(someTimeForIEToStart);
		}, Accordeon.EXPAND_INTERVAL);
	}
}
Accordeon.prototype._close = function(index) {
	if (index != null) {
		if (index == this.openedField) {
			this.openedField = null;
		}
		
		this.operationInProgress = true;
		
		clearInterval(this.collapseWaiter);

		var obj = this;
		
		this.collapseWaiter = setInterval(function() {
			if (parseInt(obj.collection[index].field.style.height) > Accordeon.MIN_ELEMENT_HEIGHT) {
				obj.collection[index].field.style.height = 
					Fibonacci.GET_PREV(parseInt(obj.collection[index].field.style.height)) + "px";
			} else {
				obj.collection[index].field.style.height = Accordeon.MIN_ELEMENT_HEIGHT + "px";
				obj.operationInProgress = false;
				obj.collection[index].field.style.visibility = "hidden";
				clearInterval(obj.collapseWaiter);
				Cookies.instance().deleteCookie("menuCategory");
			}
			
		}, Accordeon.COLLAPSE_INTERVAL);
	}
}

function initAccordeon() {
	var accordeonObject = new Accordeon();
	accordeonObject.initFieldPair(document.getElementById("accordeon_orange"), document.getElementById("orange"));
	accordeonObject.initFieldPair(document.getElementById("accordeon_green"), document.getElementById("green"));
	accordeonObject.initFieldPair(document.getElementById("accordeon_blue"), document.getElementById("blue"));
}

var elementsCollection = {};
function activateSubMenu(obj) {
	for (var section in elementsCollection) {
		for (var i in elementsCollection[section]) {
			if (elementsCollection[section][i] == obj) {
				Cookies.instance().setCookie("menuItem", i);
				elementsCollection[section][i].id = "aciveSubMenu" + section;
			} else {
				elementsCollection[section][i].id = "";
			}
		}
	}
}
function _initSubMenu(section, obj) {
	if (!elementsCollection[section]) {
		elementsCollection[section] = new Array();
	}
	elementsCollection[section].push(obj);
}
function initSubMenuElements() {
	var elementSuffixes = ["Orange", "Green", "Blue"];
	for (var c = 0; c < elementSuffixes.length; c++) {
		var container = document.getElementById("container" + elementSuffixes[c]);
		
		for (var i = 0; i < container.childNodes.length; i++) {
			try {
				if (container.childNodes[i].nodeName == "LI") {
					for (var j = 0; j < container.childNodes[i].childNodes.length; j++) {
						if (container.childNodes[i].childNodes[j].nodeName == "A") {
							_initSubMenu(elementSuffixes[c], container.childNodes[i].childNodes[j]);
						}
					}
				}
			} catch (e) {
				
			}
		}
	}
}
