var ThemeElement = Class.create();
ThemeElement.prototype = {
	initialize: function (container, jsonObj) {
		this.container = container;
		this.jsonObj = jsonObj;

		this.button = document.createElement('div');
		this.button.style.backgroundPosition = '-' + (this.jsonObj.button_bl_i * 40) + 'px top';
		this.button.title = this.jsonObj.name;
		this.button.onclick = this.onButtonClick.bind(this);

		this.container.buttonsContainer.appendChild(this.button);

		this.animationElement = document.createElement ('div');
		this.animationElement.className = "th";
		this._reflectionWidth = this.container.previewImgWidth;
		this._reflectionHeight = this.container.previewImgHeight;
		this.previewImg = new Image()
		//this.previewImg.onload = this.buildReflection.bind(this);

	},
	delayedAppend: function () {
		this.animationElement.appendChild (this.previewImg);
		if (this.container.useCanvasReflection)
			this._reflectionHeightCoef = this.container.canvasDefH / this.container.canvasDefW;
		else
			this._reflectionHeightCoef = this.container.previewImgHeight / this.container.previewImgWidth;
		this.previewImg.src = this.jsonObj.previewImg;
		this.previewImg.title = this.jsonObj.name;
		this.previewImg.className = 'preview_img';
		this.previewImg.onload = this.buildReflection.bind(this);
		this.container.coverflowElement.appendChild (this.animationElement);
	},

	buildReflection: function () {
		if (this.container.useCanvasReflection) {
			var canvas = document.createElement('canvas');
			if (canvas.getContext) {
				canvas.className = 'reflection';
				//canvas.style.height = this.container.previewImgHeight + "px";
				canvas.style.height = this._reflectionHeight + "px";
				canvas.style.width = this._reflectionWidth + "px";
				this.animationElement.appendChild(canvas);
				var context = canvas.getContext("2d");
				context.save();

				context.translate(0,this.container.canvasDefH-1);
				context.scale(1,-1);

				context.drawImage(this.previewImg, 0, 0, this.container.canvasDefW , this.container.canvasDefH);
				context.restore();

				context.globalCompositeOperation = "destination-out";
				var gradient = context.createLinearGradient(0, 0, 0, this.container.previewImgHeight);
				gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
				gradient.addColorStop(0.2, "rgba(255, 255, 255, 1.0)");
				gradient.addColorStop(0, "rgba(255, 255, 255, 0)");
				context.fillStyle = gradient;
				if (navigator.appVersion.indexOf('WebKit') != -1 && navigator.appVersion.indexOf('Chrome') == -1)
					context.fill();
				else
					context.fillRect(0, 0, this.container.canvasDefW, this.container.canvasDefH);
				this.reflectionElement = canvas;
			}
		} else {
			var reflection = document.createElement('img');
			reflection.src = this.previewImg.src;
			reflection.className = 'ie_reflection';
			reflection.style.left = "0px";
			/*reflection.style.width = "px";
			reflection.style.height = this.relaxedElement.height - 10 + "px";*/
			reflection.style.filter = 'flipv progid:DXImageTransform.Microsoft.Alpha(opacity=100, style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=20)';
			this.reflectionElement = reflection;
			this.animationElement.appendChild(reflection);
		}
	},

	OnClick: function (event) {
		this.container.changeTheme(this.filesName);
	},
	onButtonClick: function () {
		this.container.animateTo(this);
	},
	setSizeAndPosition: function (x, y, w, z, d) { // X, Y, Width, Z Index, Display (bool)
		if (d) {
			this.animationElement.style.display = 'block';
			this.animationElement.style.left = x + "px";
			this.animationElement.style.top = y + "px";
			this.animationElement.style.width = w + "px";
			this.previewImg.style.width = w + "px";
			this._reflectionWidth = w;
			this._reflectionHeight = w * this._reflectionHeightCoef;
			if (this.reflectionElement) {
				this.reflectionElement.style.width = this._reflectionWidth + "px";
				this.reflectionElement.style.height = this._reflectionHeight + "px";
			}
			this.animationElement.style.zIndex = z;
		} else this.animationElement.style.display = 'none';
	},
	setTop: function () {
		this.container.themeNameElement.innerHTML = this.jsonObj.name;
	},
	unsetTop: function () {

	}
}


var ThemesChooser = {
	themes: [
        {name:'Dusk', filesName: 'default', button_bl_i: 0, previewImg: '/images/themes_previews/dusk.png', playerXML: 'default'},
        {name:'Sky', filesName:'sky', button_bl_i: 1, previewImg: '/images/themes_previews/sky.png', playerXML: '/themes/sky.player.xml'},
        {name:'Chocolate', filesName:'Chocolate', button_bl_i: 2, previewImg: '/images/themes_previews/chocolate.png', playerXML: '/themes/Chocolate.player.xml'},
        {name:'Nature', filesName:'Nature', button_bl_i: 3, previewImg: '/images/themes_previews/nature.png', playerXML: '/themes/Nature.player.xml'},
        {name:'Royal Pink', filesName:'RoyalPink', button_bl_i: 4, previewImg: '/images/themes_previews/royalpink.png', playerXML: '/themes/RoyalPink.player.xml'},
        {name:'White Blue', filesName:'White.blue', button_bl_i: 5, menuTextColor: '017ED2', previewImg: '/images/themes_previews/white.blue.png', playerXML: '/themes/White.blue.player.xml'},
    	{name:'White Green', filesName:'White.green', button_bl_i: 6, menuTextColor: '1b741b', previewImg: '/images/themes_previews/white.green.png', playerXML: '/themes/White.green.player.xml'},
    	{name:'White Navy', filesName:'White.navy', button_bl_i: 7, menuTextColor: '197272', previewImg: '/images/themes_previews/white.navy.png', playerXML: '/themes/White.navy.player.xml'},
    	{name:'White Black', filesName:'White.black', button_bl_i: 8, menuTextColor: '000000', previewImg: '/images/themes_previews/white.black.png', playerXML: '/themes/White.black.player.xml'},
    	{name:'White Orange', filesName:'White.orange', button_bl_i: 9, menuTextColor: '9c3403', previewImg: '/images/themes_previews/white.orange.png', playerXML: '/themes/White.orange.player.xml'},
    	{name:'White Red', filesName:'White.red', button_bl_i: 10, menuTextColor: 'b81f25', previewImg: '/images/themes_previews/white.red.png', playerXML: '/themes/White.red.player.xml'},
    	{name:'White Violet', filesName:'White.violet', button_bl_i: 11, menuTextColor: '7a23bc', previewImg: '/images/themes_previews/white.violet.png', playerXML: '/themes/White.violet.player.xml'},
		{name:'Black Blue', filesName:'Black.blue', button_bl_i: 12, menuTextColor: '006899', previewImg: '/images/themes_previews/black.blue.png', playerXML: '/themes/Black.blue.player.xml'},
    	{name:'Black White', filesName:'Black.white', button_bl_i: 13, menuTextColor: 'FFFFFF', previewImg: '/images/themes_previews/black.white.png', playerXML: '/themes/Black.white.player.xml'},
    	{name:'Black Green', filesName:'Black.green', button_bl_i: 14, menuTextColor: '5a9c01', previewImg: '/images/themes_previews/black.green.png', playerXML: '/themes/Black.green.player.xml'},
    	{name:'Black Orange', filesName:'Black.orange', button_bl_i: 15, menuTextColor: 'da5618', previewImg: '/images/themes_previews/black.orange.png', playerXML: '/themes/Black.orange.player.xml'},
    	{name:'Black Red', filesName:'Black.red', button_bl_i: 16, menuTextColor: 'ff3d3d', previewImg: '/images/themes_previews/black.red.png', playerXML: '/themes/Black.red.player.xml'},
    	{name:'Black Violet', filesName:'Black.violet', button_bl_i: 17, menuTextColor: 'a44ce7', previewImg: '/images/themes_previews/black.violet.png', playerXML: '/themes/Black.violet.player.xml'},
    	{name:'Black Navy', filesName:'Black.navy', button_bl_i: 18, menuTextColor: '0ca79c', previewImg: '/images/themes_previews/black.navy.png', playerXML: '/themes/Black.navy.player.xml'},
    	{name:'Black Yellow', filesName:'Black.yellow', button_bl_i: 19, menuTextColor: 'ab7201', previewImg: '/images/themes_previews/black.yellow.png', playerXML: '/themes/Black.yellow.player.xml'}
	],

	reflectionHeightCoef: 0.2,
	previewImgWidth: 190, previewImgHeight: 178,
	canvasDefW: 300, canvasDefH: 150,
	firstTimeBoxOpen: true,

	initialize: function () {
		this.element = $('theme_chooser_box');
		this.buttonsContainer = $('themes_buttons');
		this.coverflowElement = $('themes_cf_in');
		this.themeNameElement = $('themes_cf_name');
		this.useCanvasReflection = !(document.all && !window.opera);

		this.items = new Array();

		for (var i = 0; i < this.themes.length; i ++ ) {
			this.items.push (new ThemeElement (this, this.themes[i]));
		}

		this.currentTheme = this.topTheme = this.items[0];

		this.initAnimation();

		if (onl_settheme) {
			this.changeTheme(onl_settheme)
		}else {
			var t = Cookies.getValue('theme', 'default');
			this.changeTheme(t);
		}

		Event.observe (this.coverflowElement, "mousewheel", this.onMouseWheel.bindAsEventListener(this));
	},

	changeTheme: function (themeFiles) {
		if (current_theme == themeFiles) return true;
		Cookies.setValue('theme', themeFiles);
		mb.hideAll();
		this.updateTheme(themeFiles);
		if (user_name) {
			new Ajax.Request('save_settings.php',
				{method:'post', parameters:'theme=' + themeFiles});
		}
	},
	getThemeByFilesName: function (themeFiles) {
		for (var i = 0; i < this.items.length; i ++)
			if (this.items[i].jsonObj.filesName == themeFiles) return this.items[i];
		return null;
	},
	getIndexOfTheme: function (theme) {
		for (var i = 0; i < this.items.length; i ++)
			if (this.items[i] == theme) return i;
		return -1;
	},
	openBox: function () {
		showBackground();
		this.element.style.display = 'block';
		if (this.firstTimeBoxOpen) {
			for (var i = 0; i < this.items.length; i ++)
				this.items[i].delayedAppend();
			this.firstTimeBoxOpen = false;
		}
	},
	closeBox: function () {
		hideBackground();
		this.element.style.display = 'none';
	},

	onClickOK: function () {
		this.changeTheme(this.topTheme.jsonObj.filesName);
		this.closeBox();
	},

	updateTheme: function (new_theme) {
		if (current_theme == new_theme)	return true;
		this.setTopTheme(this.getThemeByFilesName(new_theme));
		// update the style tag innerHTML
		var style_tag = $('theme_css_link');
		style_tag.disabled = true;
		style_tag.href = SHOST + "/themes/" + new_theme + ".css";
		style_tag.disabled = false;
		current_theme = new_theme;
		this.currentTheme = this.getThemeByFilesName(new_theme);
		new Ajax.Request ('/themes/' + new_theme + '.main.js', {
			method: "get", onSuccess: this.updateTheme_handler.bind(this) });
	},

	updateTheme_handler: function (ajaxResponse) {
		try {
			eval (ajaxResponse.responseText);
		} catch (e) {
		}
		search (1, last_list_by, false, last_search_string, last_related_video_id);
		bc.onThemeChange();
		Converter.onThemeChange();
	},

	setTopTheme: function (theme) {
		if (this.topTheme == theme) return;
		this.topTheme = theme;
		this.currentFrame = this.topTheme._frameOnTop;
		this.topTheme.setTop();
		this.updateAnimation();
	},

	// the coverflow animation shits
	initAnimation: function () {
		this.framesPerSwap = 5;
		this.maxFrame = 1 + this.framesPerSwap * (this.themes.length - 1);
		this.currentFrame = this.getIndexOfTheme(this.currentTheme) * this.framesPerSwap;
		this.topTheme = this.currentTheme;
		// recalculate all frames and store in array for smooth animation

		this.frames = new Array ();
		this.themesCount = this.themes.length;

		// first - some optimization values
		for (var i = 0; i < this.items.length; i ++) {
			this.items[i]._frameOnTop = i * this.framesPerSwap;
			this.items[i]._frameOnLeft = (i + 1) * this.framesPerSwap;
			this.items[i]._frameOnRight = (i - 1) * this.framesPerSwap;
			this.items[i]._rightStackZ = this.themesCount - i;
			this.items[i]._leftStackZ = i;
		}

		// init the arrays
		for (var frame = 0; frame < this.maxFrame; frame++) {
			this.frames[frame] = new Array ();
		}
		//some configuration values
		this.rightStackX = 350;
		this.leftStackX = 0;
		this.leftStackY = this.rightStackY = 40;
		this.leftStackW = this.rightStackW = 120;
		this.topW = 190;
		this.topX = 140;
		this.topY = 10;
		this.animZ = this.themesCount + 1;
		this.topZ = this.themesCount + 2;
		// calculate some delta values for the animation
		var ldw = (this.topW - this.leftStackW) / this.framesPerSwap;
		var ldx = (this.topX - this.leftStackX) / this.framesPerSwap;
		var ldy = (this.topY - this.leftStackY) / this.framesPerSwap;
		var rdw = (this.rightStackW - this.topW) / this.framesPerSwap;
		var rdx = (this.rightStackX - this.topX) / this.framesPerSwap;
		var rdy = (this.rightStackY - this.topY) / this.framesPerSwap;
		for (var th = 0; th < this.themesCount; th ++) {
			// in this frames the theme is somewhere in the right stack
			for (var i = 0; i < this.items[th]._frameOnRight; i ++) {
				this.frames[i][th] = {x:this.rightStackX, y:this.rightStackY, w:this.rightStackW, z:this.items[th]._rightStackZ, d:true};
			}

			// in this frames the theme is sliding from right to top
			if (this.items[th]._frameOnRight >= 0)
				for (var i = this.items[th]._frameOnRight, j = 0; i < this.items[th]._frameOnTop; i ++, j ++) {
					this.frames[i][th] = {x: this.rightStackX - rdx * j, y: this.rightStackY - rdy * j, w: this.rightStackW - rdw * j, z: this.animZ, d:true};
				}
			// in this frames the theme is sliding from top to left
			if (this.items[th]._frameOnLeft < this.maxFrame)
				for (var i = this.items[th]._frameOnTop, j = 0; i < this.items[th]._frameOnLeft; i ++, j ++) {
					this.frames[i][th] = {x: this.topX - ldx * j, y: this.topY - ldy * j, w: this.topW - ldw * j, z: this.animZ, d:true};
				}

			this.frames[this.items[th]._frameOnTop][th] = {x: this.topX, y: this.topY, w: this.topW, z: this.topZ, d:true};

			// in this frames the theme is somewhere in the left stack
			for (var i = this.items[th]._frameOnLeft; i < this.maxFrame; i ++) {
				this.frames[i][th] = {x:this.leftStackX, y:this.leftStackY, w:this.leftStackW, z:this.items[th]._leftStackZ, d:true};
			}

			// fix display value
			for (var i = 0; i <= this.items[th]._frameOnRight - this.framesPerSwap; i ++)
				this.frames[i][th].d = false;
			for (var i = this.items[th]._frameOnLeft + this.framesPerSwap; i < this.maxFrame; i ++)
				this.frames[i][th].d = false;
		}
		this._onAnimT = this.onAnimationTimer.bind(this);

		this.updateAnimation();// initialize!
		this.topTheme.setTop();
	},
	updateAnimation: function () {
		var frame = this.frames[this.currentFrame];
		for (var i = 0; i < this.themesCount; i ++)
			try {
				this.items[i].setSizeAndPosition (frame[i].x, frame[i].y, frame[i].w, frame[i].z, frame[i].d);
			} catch (e) { }
	},
	animateTo: function (theme) {
		if (this.topTheme == theme) return;
		this.topTheme.unsetTop();
		var ti = this.getIndexOfTheme(theme);
		this.destinationFrame = this.items[ti]._frameOnTop;
		this.destinationTheme = theme;
		this.themeNameElement.innerHTML = '';
		if (this._animationTimer)
			clearInterval(this._animationTimer);
		//this.startAnimationAt = new Date();
		this._animationTimer = setInterval (this._onAnimT, 30);
	},
	onAnimationTimer: function () {
		if (this.destinationFrame > this.currentFrame)
			this.currentFrame++;
		else
			this.currentFrame--;
		this.updateAnimation();
		if (this.currentFrame == this.destinationFrame) {
			clearInterval (this._animationTimer);
			this._animationTimer = null;
			this.onAnimationEnd();
		}
	},
	onAnimationEnd: function () {
		this.topTheme = this.destinationTheme;
		this.topTheme.setTop();
		//var endAnimationAt = new Date();
		//alert ('Took: ' + (endAnimationAt.getTime() - this.startAnimationAt.getTime()) + ' ms');
	},
	onNextClick: function () {
		var ti = this.getIndexOfTheme(this.topTheme);
		if (ti < this.themesCount - 1) {
			ti ++;
			this.animateTo (this.items[ti]);
		}
	},
	onPrevClick: function () {
		var ti = this.getIndexOfTheme(this.topTheme);
		if (ti > 0) {
			ti --;
			this.animateTo (this.items[ti]);
		}
	},

	onMouseWheel: function (event) {
		var d = Event.wheelDelta (event);
		if (d == 0) return true;
		var frame = this.currentFrame;
		var rt = Math.round(this.currentFrame / this.framesPerSwap);
		if (d > 0) {
			rt +=1;
		} else {
			rt -=1;
		}

		if (rt >= 0 && rt < this.items.length)
			this.animateTo(this.items[rt]);
	},
	getCurrentThemeName: function () {
		return this.currentTheme.jsonObj.name;
	}
}
