Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

var IRSubMenu = Class.create({
	initialize: function (parentMenuItem, itemMap) {
		this.parentItem = parentMenuItem;
	}
});

var IRLargeButtonManager = Class.create({
	initialize: function (parentElement, buttonIds) {
		this.bIds = buttonIds;
		this.buttonOutElements = {};
		this.buttonOverElements = {};
		var textSection = $(parentElement);
		this.parentElementID = parentElement;
		this.parentElementObj = textSection;
		var buttonContainers = textSection.select('div.buttonLargeContainer').toArray();
		for(i = 0; i < buttonContainers.length; i++) {
			var item = buttonContainers[i];
			var buttonId = buttonIds[i];
			/*--------------------------------------------------------------------------------*/
			var buttonEl = new Element('div', {'class': 'buttonLarge'});
			buttonEl.writeAttribute({'id': buttonId+'Out'});
			buttonEl.style.backgroundImage="url(" + outImgs[buttonId] + ")";
			buttonEl.setStyle({'top': '0px', zIndex: '2'});
			
			var bLabel = new Element('div', {'class': 'buttonLabel'});
			bLabel.setStyle({'margin-left': buttonLabelX[buttonId], 'top': buttonLabelY[buttonId]});
			var bLabelHeader = new Element('span', {'class': 'header'});
			bLabelHeader.update(outHeaders[buttonId]);
			var bLabelDescription = new Element('span', {'class': 'description'});
			bLabelDescription.update(nl2br(outDescriptions[buttonId]));
			
			bLabel.insert(bLabelHeader);
			bLabel.insert(new Element('br', {}));
			bLabel.insert(bLabelDescription);
			buttonEl.insert(bLabel);
			/*--------------------------------------------------------------------------------*/
			
			/*--------------------------------------------------------------------------------*/
			var buttonElHover = new Element('div', {'class': 'buttonLarge'});
			buttonElHover.writeAttribute({'id': buttonId + 'Over'});
			buttonElHover.style.backgroundImage="url(" + overImgs[buttonId] + ")";
			buttonElHover.setStyle({'top': '-250px', marginBottom: '-250px', zIndex: '1'});
			

			
			var bLabelH = new Element('div', {'class': 'buttonLabel'});
			bLabelH.setStyle({'left': buttonLabelX[buttonId], 'top': buttonLabelY[buttonId]});
			var bLinkH = new Element('a', {'href': buttonUrls[i], 'title': ''});
			var bLabelHeaderH = new Element('span', {'class': 'header'});
			bLabelHeaderH.update(overHeaders[buttonId]);
			var bLabelDescriptionH = new Element('span', {'class': 'description'});
			bLabelDescriptionH.update(nl2br(overDescriptions[buttonId]));
			
			bLinkH.insert(bLabelHeaderH);
			bLinkH.insert(new Element('br', {}));
			bLinkH.insert(bLabelDescriptionH);
			bLabelH.insert(bLinkH);
			buttonElHover.insert(bLabelH);
			/*--------------------------------------------------------------------------------*/
			(this.buttonOutElements)[buttonId + 'Out'] = buttonEl;
			(this.buttonOverElements)[buttonId + 'Over'] = buttonElHover;
			/*--------------------------------------------------------------------------------*/
			(buttonContainers[i]).insert(buttonEl);
			(buttonContainers[i]).insert(buttonElHover);
		}
		/*this.updateHoveredButtonLabelsPositions();*/
	},
	
	updateHoveredButtonLabelsPositions: function() {
		var i = 0;
		var n = this.bIds.length;
		for(i = 0; i < n; i++) {
			var buttonOutElement = this.buttonOutElements[this.bIds[i] + 'Out'];
			var buttonOutLabel = (buttonOutElement.firstDescendant());
			var labelOutHeight = buttonOutLabel.getHeight();
			
			var buttonOverElement = this.buttonOverElements[this.bIds[i] + 'Over'];
			var buttonOverLabel = (buttonOverElement.firstDescendant());
			var labelOverHeight = buttonOverLabel.getHeight();
			
			var dY = labelOverHeight - labelOutHeight;
			var buttonLabelOverCoordinates = buttonOverLabel.positionedOffset();
			var oldY = buttonLabelOverCoordinates.top;
			var newY = oldY - dY;
			buttonOverLabel.setStyle({'top': newY + 'px'});
		}
	},
	
	getButtonIds: function() {
		return this.bIds;
	},
	
	getOutButtonElements: function() {
		return this.buttonOutElements;
	},
	
	getOverButtonElements: function() {
		return this.buttonOverElements;
	},
	
	setButtonOver: function (buttonId, isOver) {
		var buttonOut = (this.buttonOutElements)[buttonId];
		var buttonOver = (this.buttonOverElements)[buttonId];
		if(isOver) {
			buttonOut.hide();
			buttonOver.show();
		}
		else {
			buttonOut.show();
			buttonOver.hide();
		}
	}
});

var IRLargeButtonHandler = Class.create({
	
	initialize: function(lButtonManager) {
		this.buttonsArray = new Array();
		this.largeButtonManager = lButtonManager;
		this.bInitialized = false;
		var i = 0;
		var btnIds = lButtonManager.getButtonIds();
		var n = btnIds.length;
		var buttonOutElems = lButtonManager.getOutButtonElements();
		var buttonOverElems = lButtonManager.getOverButtonElements();
		var largeButtonsOutHandler = this.largeButtonsOutHandlerFunction.bindAsEventListener(this);
		Event.observe(this.largeButtonManager.parentElementID, 'mousemove', largeButtonsOutHandler);
		for(i = 0; i < n; i++) {
			var buttonOutElement = buttonOutElems[btnIds[i]+'Out'];
			var buttonOverElement = buttonOverElems[btnIds[i]+'Over'];
			var largeButtonOverHandler = this.largeButtonOverHandlerFunction.bindAsEventListener(this, buttonOutElement, buttonOverElement);
			Event.observe(btnIds[i], 'mousemove', largeButtonOverHandler);
		}
		this.largeButtonManager.updateHoveredButtonLabelsPositions();
		this.bInitialized = true;
	},
	
	largeButtonOverHandlerFunction: function(event, buttonOutElement, buttonOverElement) {
		if(!(this.bInitialized)) {
			this.largeButtonManager.updateHoveredButtonLabelsPositions();
			this.bInitialized = true;
		}
		var buttonOverCoordinates = buttonOverElement.viewportOffset()
		var buttonDimensions = buttonOverElement.getDimensions();
		
		var x0 = buttonOverCoordinates.left;
		var y0 = buttonOverCoordinates.top;
		var x1 = x0 + buttonDimensions.width;
		var y1 = y0 + buttonDimensions.height;
		
		var pX = Event.pointerX(event);
		var pY = Event.pointerY(event);
		
		if(pX > x0 && pX < x1 && pY > y0 && pY < y1) {
			buttonOverElement.setStyle({zIndex: '2'});
			buttonOutElement.setStyle({zIndex: '1'});
			
			if(this.buttonsArray[buttonOutElement.identify()] == undefined || this.buttonsArray[buttonOutElement.identify()] == null) {
				this.buttonsArray.push(buttonOutElement.identify());
			}
		}
	},
	
	largeButtonsOutHandlerFunction: function(event) {
		var n = this.buttonsArray.length;
		var i = 0;
		for(i = 0; i < n; i++) {
			var buttonElementId = this.buttonsArray[i];
			
			var buttonCoordinates = $(buttonElementId).viewportOffset()
			var buttonDimensions = $(buttonElementId).getDimensions();
		
			var x0 = buttonCoordinates.left;
			var y0 = buttonCoordinates.top;
			var x1 = x0 + buttonDimensions.width;
			var y1 = y0 + buttonDimensions.height;
		
			var pX = Event.pointerX(event);
			var pY = Event.pointerY(event);
		
			if((pX > x0 && pX < x1 && pY > y0 && pY < y1) == false) { /*TODO: dvv: Not sure it removes Ids from array perfectly*/
				$(buttonElementId.substring(0, buttonElementId.length - 3) + 'Over').setStyle({zIndex: '1'});
				$(buttonElementId).setStyle({zIndex: '2'});
				this.buttonsArray.remove(i);
				break;
			}
		}
	}
});

function nl2br(text){
	var origText = text;
	text = escape(text);
	if(text.indexOf('%0D%0A') > -1) {
		re_nlchar = /%0D%0A/g;
	} else if(text.indexOf('%0A') > -1) {
		re_nlchar = /%0A/g;
	} else if(text.indexOf('%0D') > -1) {
		re_nlchar = /%0D/g;
	}
	else {
		return origText;
	}
	return unescape( text.replace(re_nlchar,'<br />') );
}