var MenuItem = Class.create();
MenuItem.prototype = {
	initialize: function (container, icon_url, text, handler) {
		this.container = container;
		this.element = document.createElement('div');
		this.element.className = 'popup_menu_item';
		this.icon = document.createElement('img');
		this.icon.src = icon_url;

		if (icon_url) this.element.appendChild(this.icon);
		this.element.appendChild(document.createTextNode(text));

		this.container.element.appendChild(this.element);
		this.mouseClickHandler = handler;

		this.element.onmouseover = this.onMouseOver.bindAsEventListener(this);
		this.element.onmouseout = this.onMouseOut.bindAsEventListener(this);
		this.element.onclick = this.onMouseClick.bindAsEventListener(this);
		this.icon.onclick = this.element.onclick;
	},

	onMouseClick: function (event) {
		this.container.close;
		if (this.mouseClickHandler)
			this.mouseClickHandler(event);
		Event.stop(event);
	},

	onMouseOver: function (event) {
		Element.addClassName (this.element, 'hover_popup_item');
	},

	onMouseOut: function (event) {
		Element.removeClassName (this.element, 'hover_popup_item');
	}
}

var PopupMenu = Class.create ();
PopupMenu.prototype = {
	initialize: function (items) { // items = Array {text, handler(event)}
		this.element = document.createElement('div');
		this.element.className = 'popup_menu';
		$('popup_container').appendChild(this.element);

		this.items = new Array ();
		for (var i = 0; i < items.length; i ++)
			this.items.push (new MenuItem (this, items[i].icon_url, items[i].text, items[i].handler));
	},

	popup: function (event) {
		this.element.style.left = Event.pointerX(event) + "px";
		var wi = (window.innerHeight > 0 ? window.innerHeight : document.documentElement.clientHeight);
		this.element.style.bottom = (wi - Event.pointerY(event)) + "px";
		this.element.style.display = "block";
	},

	close: function (event) {
		this.element.style.display = "none";
	},

	remove: function () {
		$('popup_container').removeChild(this.element);
	}
}

var TrayItem = Class.create();
TrayItem.prototype = {
	initialize: function (container) {
		this.container = container;

		//this.element = document.createElement('div');
		this.img = document.createElement('img');

		this.img.style.height = this.container.relaxedElement.height + "px";
		this.img.style.width = this.container.relaxedElement.width + "px";
		this.img.className = 'tray_item';
		this.img.onmouseover = this.onMouseOver.bindAsEventListener(this);
		this.img.onmouseout = this.onMouseOut.bindAsEventListener(this);
		this.img.onclick = this.onMouseClick.bindAsEventListener(this);
		this.reflection = document.createElement('img');
		this.reflection.className = 'tray_reflection';
		this.reflection.style.width = this.img.style.width;

		this.ajaxLoading = document.createElement('img');
		this.ajaxLoading.src = 'images/indicator.white.gif';
		this.ajaxLoading.className = 'tray_ajaxLoading';

		this.div_info = document.createElement ('div');
		this.div_info.className = 'tray_item_title';
		this.div_outer = document.createElement ('div');

		this.div_title = document.createElement('div');
		this.div_status = document.createElement('div');
		this.div_status.className = 'status';
		this.div_hint = document.createElement('div');
		this.div_hint.className = 'tray_download_hint';
		this.div_hint.innerHTML = 'Right click to select download format';
		this.div_outer.appendChild(this.div_title);
		this.div_outer.appendChild(this.div_status);
		this.div_outer.appendChild(this.div_hint);

		this.div_operations = document.createElement('div');
		this.div_operations.className = 'tray_item_operations';

		this.div_progress_bar = document.createElement('div');
		this.div_progress_bar.className  = 'tray_progress_bar';

		this.container.element.appendChild(this.img);
		this.container.element.appendChild(this.reflection);
		this.container.element.appendChild(this.ajaxLoading);
		this.container.element.appendChild(this.div_info);
		this.container.element.appendChild(this.div_operations);
		this.div_info.appendChild(this.div_progress_bar);
		this.div_info.appendChild(this.div_outer);

		this.element = this.img;

		this.alertObject = new ElementHintFading ({});

		this.container.element.appendChild(this.alertObject.element);
	},

	setObjectPlayer: function (jsonObj, player) {
		if (jsonObj == null) {
			this.div_title.innerHTML = 'Empty player...';
		} else {
			this.jsonObj = jsonObj;

			this.img.src = this.jsonObj.thumbnail_url;
			this.reflection.src = this.jsonObj.thumbnail_url;
			this.div_title.innerHTML = jsonObj.title;
		}

		if (!this.beenHereOnce) {
			this.beenHereOnce = true;
		} else return;

		this.img_remove = document.createElement('img');
		this.img_remove.src = 'images/tray/ico_remove.gif';
		this.img_remove.title = 'Remove';
		if (this.div_operations.childNodes.length == 0)
			this.div_operations.appendChild (this.img_remove);

		dnd.registerDrop(this);

		this.popupMenu = new PopupMenu(Array(
			{text:'Minimize', icon_url:'',handler:player.minimize.bindAsEventListener(player)},
			{text:'Restore', icon_url:'',handler:player.onClickTray.bindAsEventListener(player)},
			{text:'Close', icon_url:'images/tray/ico_remove.gif',handler:player.closeBox.bindAsEventListener(player)}
		));

		this.img_remove.onclick = player.closeBox.bindAsEventListener(player);
		this.img.onclick = player.onClickTray.bind(player);
		this.img.oncontextmenu = this.onMouseClick.bindAsEventListener(this);
		this.img.onmousedown = this.onMouseClick.bindAsEventListener(this);
	},

	setObjectDownload: function (jsonObj, conversion) {
		this.jsonObj = jsonObj;
		this.img.src = this.jsonObj.thumbnail_url;
		this.reflection.src = this.jsonObj.thumbnail_url;
		this.div_title.innerHTML = jsonObj.title;
		this.showAjaxLoading();

		this.img_downloadExe = document.createElement('img');
		this.img_downloadExe.src = 'images/tray/ico_exe.gif';
		this.img_downloadExe.title = 'Save as Exe';

		this.img_downloadFlv = document.createElement('img');
		this.img_downloadFlv.src = 'images/tray/ico_flv.gif';
		this.img_downloadFlv.title = 'Save as Flv (Flash)';

		this.img_downloadZip = document.createElement('img');
		this.img_downloadZip.src = 'images/tray/ico_zip.gif';
		this.img_downloadZip.title = 'Save as Zip (EXE)';

		this.img_downloadMp3 = document.createElement('img');
		this.img_downloadMp3.src = 'images/tray/ico_mp3.gif';
		this.img_downloadMp3.title = 'Save as MP3 (Audio only)';

		this.img_downloadAvi = document.createElement('img');
		this.img_downloadAvi.src = 'images/tray/ico_avi.gif';
		this.img_downloadAvi.title = 'Save as Avi (For Windows)';

		this.img_downloadMov = document.createElement('img');
		this.img_downloadMov.src = 'images/tray/ico_mov.gif';
		this.img_downloadMov.title = 'Save as Mov (For QuickTime)';

		this.img_downloadMp4 = document.createElement('img');
		this.img_downloadMp4.src = 'images/tray/ico_mp4.gif';
		this.img_downloadMp4.title = 'Save as MP4 (For iPod/iPhone)';
		/*
		this.img_download3gp = document.createElement('img');
		this.img_download3gp.src = 'images/tray/ico_3gp.gif';
		this.img_download3gp.title = 'Save as 3GP (For Mobile Phones)';
		*/
		this.img_download3g2 = document.createElement('img');
		this.img_download3g2.src = 'images/tray/ico_3gpp.gif';
		this.img_download3g2.title = 'Save as 3GP2 (For Newer Mobile Phones)';

		this.img_downloadWmv = document.createElement('img');
		this.img_downloadWmv.src = 'images/tray/ico_wmv.gif';
		this.img_downloadWmv.title = 'Save as WMV (For Windows)';

		this.img_downloadWma = document.createElement('img');
		this.img_downloadWma.src = 'images/tray/ico_wma.gif';
		this.img_downloadWma.title = 'Save as WMA (Audio only, for Windows)';

		this.img_downloadAac = document.createElement('img');
		this.img_downloadAac.src = 'images/tray/ico_aac.gif';
		this.img_downloadAac.title = 'Save as AAC (Audio only)';

		this.img_Play = document.createElement('img');
		this.img_Play.src = 'images/tray/ico_play.gif';
		this.img_Play.title = 'Play';

		this.img_remove = document.createElement('img');
		this.img_remove.src = 'images/tray/ico_remove.gif';
		this.img_remove.title = 'Remove';

		this.div_operations.appendChild (this.img_Play);
		this.div_operations.appendChild (this.img_remove);
		this.div_operations.appendChild (this.img_downloadExe);
		//this.div_operations.appendChild (this.img_downloadFlv);
		this.div_operations.appendChild (this.img_downloadZip);
		this.div_operations.appendChild (this.img_downloadAvi);
		this.div_operations.appendChild (document.createElement('BR'));
		this.div_operations.appendChild (this.img_downloadWmv);
		this.div_operations.appendChild (this.img_downloadMov);
		this.div_operations.appendChild (this.img_download3g2);
		this.div_operations.appendChild (this.img_downloadWma);
		this.div_operations.appendChild (this.img_downloadAac);
		this.div_operations.appendChild (this.img_downloadMp3);
		
		//this.div_operations.appendChild (this.img_downloadMp4);
		//this.div_operations.appendChild (this.img_download3gp);

		this.img_downloadExe.onclick = conversion.click_downloadAsEXE.bindAsEventListener (conversion);
		//this.img_downloadFlv.onclick = conversion.click_downloadAsFLV.bindAsEventListener (conversion);
		this.img_downloadZip.onclick = conversion.click_downloadAsZIP.bindAsEventListener (conversion);
		this.img_downloadAvi.onclick = conversion.click_downloadAsAVI.bindAsEventListener (conversion);
		this.img_downloadMov.onclick = conversion.click_downloadAsMOV.bindAsEventListener (conversion);
		this.img_downloadMp4.onclick = conversion.click_downloadAsMP4.bindAsEventListener (conversion);
		//this.img_download3gp.onclick = conversion.click_downloadAs3GP.bindAsEventListener (conversion);
		this.img_download3g2.onclick = conversion.click_downloadAs3G2.bindAsEventListener (conversion);
		this.img_downloadWmv.onclick = conversion.click_downloadAsWMV.bindAsEventListener (conversion);
		this.img_downloadMp3.onclick = conversion.click_downloadAsMP3.bindAsEventListener (conversion);
		this.img_downloadWma.onclick = conversion.click_downloadAsWMA.bindAsEventListener (conversion);
		this.img_downloadAac.onclick = conversion.click_downloadAsAAC.bindAsEventListener (conversion);

		this.img_Play.onclick = conversion.click_play.bindAsEventListener (conversion);
		this.img_remove.onclick = conversion.click_remove.bindAsEventListener(conversion);

		this.div_progress_bar.style.display = "block";

		this.popupMenu = new PopupMenu(Array(
			{text:'Save as AVI (For Windows)',       icon_url:'images/tray/ico_avi.gif',handler:this.img_downloadAvi.onclick},
			{text:'Save as MP4 (For iPod/iPhone)',   icon_url:'images/tray/ico_mp4.gif',handler:this.img_downloadMp4.onclick},
			{text:'Save as MOV (For Quick Time)',    icon_url:'images/tray/ico_mov.gif',handler:this.img_downloadMov.onclick},
			//{text:'Save as 3GP (For mobile phones)', icon_url:'images/tray/ico_3gp.gif',handler:this.img_download3gp.onclick},
			{text:'Save as 3GP2 (For newer mobile phones)', icon_url:'images/tray/ico_3gp.gif',handler:this.img_download3g2.onclick},
			{text:'Save as WMV (For Windows)',       icon_url:'images/tray/ico_wmv.gif',handler:this.img_downloadWmv.onclick},
			//{text:'Save as FLV (For Flash)', icon_url:'images/tray/ico_flv.gif',handler:this.img_downloadFlv.onclick},
			{text:'Save as EXE', icon_url:'images/tray/ico_exe.gif',handler:this.img_downloadExe.onclick},
			{text:'Save as ZIP', icon_url:'images/tray/ico_zip.gif',handler:this.img_downloadZip.onclick},
			{text:'Save as MP3 (Audio only)', icon_url:'images/tray/ico_mp3.gif',handler:this.img_downloadMp3.onclick},
			{text:'Save as WMA (Audio only)', icon_url:'images/tray/ico_wma.gif',handler:this.img_downloadWma.onclick},
			{text:'Save as AAC (Audio only)', icon_url:'images/tray/ico_aac.gif',handler:this.img_downloadAac.onclick},
			{text:'Remove', icon_url:'images/tray/ico_remove.gif',handler:this.img_remove.onclick},
			{text:'Play', icon_url:'images/tray/ico_play.gif',handler:this.img_Play.onclick})
		);
		this.img.oncontextmenu = this.onMouseClick.bindAsEventListener(this);
		this.img.onmousedown = this.onMouseClick.bindAsEventListener(this);
	},
	remove: function () {
		this.container.element.removeChild(this.img );
		this.container.element.removeChild(this.reflection );
		this.container.element.removeChild(this.div_operations );
		this.container.element.removeChild(this.div_info );
		this.container.element.removeChild(this.ajaxLoading);
		this.container.element.removeChild(this.alertObject.element);
		if (this.popupMenu)
			this.popupMenu.remove();
		this.container.removeFromTray(this);
	},

	onMouseOver: function (event) {
		Element.addClassName (this.img, 'hovered');
		Element.addClassName (this.reflection, 'hovered');
		this.div_info.style.display = 'block';
		this.div_operations.style.display = 'block';
		//Event.stop(event);
		this.container.mouseEnteredElement();
	},

	onMouseOut: function (event) {
		// there is the problem when the mouse is over the div with the icons so we check the coords
		if (event) {
			if (dnd.draggedIsOver(Event.pointerX(event), Event.pointerY(event), this.div_operations)) return;
			//Event.stop(event);
		}
		Element.removeClassName (this.img, 'hovered');
		Element.removeClassName (this.reflection, 'hovered');
		this.div_info.style.display = 'none';
		this.div_operations.style.display = 'none';
		this.container.mouseLeftElement();
	},

	onMouseClick: function (event) {
		if (Event.isLeftClick(event)) {
			if (this.onClick)
				this.onClick(event);
		} else {
			if (this.popupMenu) {
				this.popupMenu.popup(event);
				return false;
			}
		}
	},

	resize: function (height, left) {
		if (height > 100) height = 100;
		var w = height * this.container.relaxedElement.width / this.container.relaxedElement.height;

		this.div_info.style.left = (left + w + 4) + "px";
		this.div_info.style.bottom = (height - 50) + "px";
		this.div_operations.style.left = (left + 3) + "px";

		this.img.style.height = height + "px";
		this.img.style.left = left + "px";
		this.img.style.width = w + "px";
		this.img.style.marginTop = (this.container.element.offsetHeight - height - 10) + "px";

		this.reflection.style.width = w + "px";
		this.reflection.style.height = (height * this.container.reflectionHeightCoefficient) + "px";
		this.reflection.style.left = left + 1 + "px";

		this.ajaxLoading.style.left = left + 7 + "px";
		this.ajaxLoading.style.bottom = (height - 10) + "px";

		this.alertObject.element.style.bottom = height + 10 + "px";
		this.alertObject.element.style.left = left + "px";

		if (height < 70) {
			this.onMouseOut();
		}

		return w + 6; // 4 = marginLeft + marginTop + 2*border
	},
	dragHover: function(event, draggedObject) {
		dnd.setText('add to this player');
	},

	dragUnhover: function() {

	},

	recieveDrag: function (draggedObject) {
		if (this.trayItemReceieveDrag)
			this.trayItemReceieveDrag(draggedObject);
	},

	hideAjaxLoading: function () {
		this.ajaxLoading.style.display = 'none';
	},
	showAjaxLoading: function () {
		this.ajaxLoading.style.display = 'block';
	},
	showAlert: function (text) {
		this.alertObject.show(text);
	}
}

var Tray = {
	relaxedElement: {width: 40, height:30},
	scrollAreaWidth: 20,
	scrollSpeed: 5,
	resizeXCoefficient: 0.8,
	resizeYCoefficient: 0.4,
	reflectionHeightCoefficient: 0.2,

	initialize: function () {
		this.element = $('tray');

		this.currentLeft = 0;
		this.element.onmousemove = this.onMouseMove.bindAsEventListener(this);
		this.items = new Array ();
	},

	addToTray: function () {
		this.items.push(new TrayItem(this));
		this.relaxAll();
		return this.items[this.items.length-1];
	},

	removeFromTray: function (item) {
		this.items = this.items.without (item);
		this.relaxAll();
	},

	onMouseMove: function (event) {
		//recalc the position and sizes
		var MX = Event.pointerX (event);
		var MY = Event.pointerY (event);
		//get relative coords
		var relY = MY - this.element.offsetTop;
		var relX = MX - this.element.offsetLeft;
		if (this.element.offsetWidth < this.element.scrollWidth) {
			this.element.scrollLeft = relX * (this.element.scrollWidth - this.element.offsetWidth) / this.element.offsetWidth;
		} else {
			this.element.scrollLeft = 0;
		}
		//the very fish eye
		// the problem is that we mix the scrolling with the fish eye effect, and the fish eye effect actually changes the
		// inner width of the element, so we have to take this in account too and rescroll the element appropriate
		var inRelX = this.element.scrollLeft + relX;
		var yCoef = 0;
		if (relY > 0)
			yCoef = (this.element.offsetHeight / relY) * this.resizeYCoefficient;
		else
			yCoef = 100000;
		var cl = 0;
		var ma = 0;
		for (var i = 0; i < this.items.length; i ++) {
			ma = Math.abs(inRelX - cl - 75 ) - 30;
			if (ma < 0)
				cl += this.items[i].resize(100, cl);
			else
				cl += this.items[i].resize(Math.max(this.relaxedElement.height, (100 - yCoef * Math.pow(ma * 2, this.resizeXCoefficient) )), cl);
		}
	},

	relaxAll: function () {
		cl = 0;
		for (var i = 0; i < this.items.length; i ++) {
			cl += this.items[i].resize(this.relaxedElement.height, cl);
		}
		if (this.relaxTimeout) {
			clearTimeout (this.relaxTimeout);
			this.relaxTimeout = null;
		}
	},

	mouseEnteredElement: function () {
		if (this.relaxTimeout) {
			clearTimeout (this.relaxTimeout);
			this.relaxTimeout = null;
		}
	},
	mouseLeftElement: function () {
		if (!this.relaxTimeout) {
			this.relaxTimeout = setTimeout (this.relaxAll.bindAsEventListener(this), 8000);
		}
	},

	closeAllMenus: function () {
		for (var i = 0; i < this.items.length; i ++)
			if (this.items[i].popupMenu)
				this.items[i].popupMenu.close();
	}
}