Object.extend(Event, {
	KEY_SPACE: 32,
	KEY_PGUP: 33,
	KEY_PGDOWN: 34
});

if(!Control) var Control = {};
Control.Slider = Class.create();

Control.Slider.prototype = {
	initialize: function(handle, options) {
		var slider = this;

		this.handle = $(handle);
		this.options = options || {};

		this.album = this.options.album;
		this.link = this.album ? this.album.link : '';
		this.photo = this.options.photo;
		this.speed = parseInt(this.options.speed) || 4; // sec
		this.begin = this.getPhotoCurrentId(this.options.begin-1);
		this.current = this.begin;
		this.background = this.options.background || "black";
		this.caption = this.options.caption || true;

		this.body = {background: document.body.style.background, height: 0};

		this.started = false;
		this.paused = false;

		this.nav_btn = {
			prev: new Image, next: new Image, pause: new Image, play: new Image,
			prev_n: new Image, next_n: new Image, pause_n: new Image, play_n: new Image,
			minus: new Image, plus: new Image, stop: new Image
		};
		this.nav_btn.prev.src = 'http://i.proext.com/images/misc/photo/slide_prev.gif';
		this.nav_btn.prev_n.src = 'http://i.proext.com/images/misc/photo/slide_prev_n.gif';
		this.nav_btn.next.src = 'http://i.proext.com/images/misc/photo/slide_next.gif';
		this.nav_btn.next_n.src = 'http://i.proext.com/images/misc/photo/slide_next_n.gif';
		this.nav_btn.pause.src = 'http://i.proext.com/images/misc/photo/slide_pause.gif';
		this.nav_btn.pause_n.src = 'http://i.proext.com/images/misc/photo/slide_pause_n.gif';
		this.nav_btn.play.src = 'http://i.proext.com/images/misc/photo/slide_play.gif';
		this.nav_btn.play_n.src = 'http://i.proext.com/images/misc/photo/slide_play_n.gif';

		this.nav_btn.minus.src = 'http://i.proext.com/images/misc/photo/slide_minus.gif';
		this.nav_btn.plus.src = 'http://i.proext.com/images/misc/photo/slide_plus.gif';
		this.nav_btn.stop.src = 'http://i.proext.com/images/misc/photo/slide_close.gif';

		this.initialized = ((this.photo.length > 0) && (this.link));
	},

	getPhotoCurrentId: function(v) {
		v = parseInt(v);
		if ((!v) || (v > this.photo.length-1)) v = 0;
		if (v < 0) v = this.photo.length-1;
		return v;
	},

	getPhotoDimensions: function(id) {
		if ((this.photo[id].nt) && (this.photo[id].nw) && (this.photo[id].nh)) return {top: this.photo[id].nt, width: this.photo[id].nw, height: this.photo[id].nh};

		var w = this.photo[id].w;
		var h = this.photo[id].h;
		if ((w > this.maxWidth) || (h > this.maxHeight)) {
			var d = ((h / w) > (this.maxHeight / this.maxWidth)) ? this.maxHeight / h : this.maxWidth / w;
			w = parseInt(d*w);
			h = parseInt(d*h);
		}
		this.photo[id].nw = w+'px';
		this.photo[id].nh = h+'px';
		this.photo[id].nt = parseInt((this.maxHeight - h) / 2 + 5)+'px';
		return {top: this.photo[id].nt, width: this.photo[id].nw, height: this.photo[id].nh};
	},

	getPhotoDiv: function() {
		var dim = this.getPhotoDimensions(this.current);
		return ""+
		"<div id='slider_div' style='position: relative; text-align: center; overflow: hidden; width: "+this.maxWidth+"px; height: "+this.maxHeight+"px;'>"+
			"<img id='slider_img' style='z-index: 2; position: relative; top: "+dim.top+"; width: "+dim.width+"; height: "+dim.height+";' src='"+this.album.link+"v/"+this.photo[this.current].i+".jpg' border='0' alt=''>"+
			// caption
			"<div id='slider_caption' style='z-index: 3; position: absolute; text-align: center; top: 10px; width: 80%; left: 10%;'>"+
				"<table style='margin: 6px auto; padding: 0; border: 0;'><tr><td>"+
					"<div style='position: relative; text-align: center; height: 100%; opacity: 0.99; "+((is_ie) ? "filter: alpha(opacity=99);" : "")+"'>"+
						"<div style='position: absolute; z-index: 2; width: 100%; height: 100%; opacity: 0.7; "+((is_ie) ? "filter: alpha(opacity=70);" : "")+" background: #4E5B6D; padding: 0 6px;'></div>"+
						"<div id='slider_text' style='position: relative; z-index: 3; width: 100%; color: #fff; font-weight: bold; padding: 6px;'>"+this.photo[this.current].a+"</div>"+
					"</div>"+
				"</td></tr></table>"+
			"</div>"+
			// nav
			"<div id='slider_nav' style='z-index: 4; position: absolute; bottom: 10px; width: 80%; left: 10%;'>"+
				"<table style='position: relative; float: right; margin: 6px; border: 1px solid #C1CACF; background: #4E5B6D; padding: 2px;'><tr>"+
						"<td nowrap><img id='slider_nav_prev'><img id='slider_nav_pause'><img id='slider_nav_next'></td>"+
						"<td><img id='slider_nav_minus' class='sm'></td>"+
						"<td><b id='slider_speed'>"+this.speed+"</b> сек.</td>"+
						"<td><img id='slider_nav_plus' class='sm'></td>"+
						"<td nowrap><u id='slider_nav_caption'>"+this.getHTMLCaption()+"</u></td>"+
						"<td><img id='slider_nav_stop' class='sm'></td>"+
				"</tr></table>"+
			"</div>"+
		"</div>"+
		"<div id='slider_load' style='z-index: 7; position: absolute; top: 5px; left: 5px; color: #777; display: none;'>Загрузка...</div>";
	},

	showPhoto: function() {
		Element.hide(this.slider.load);
		Element.show(this.slider.img);
		if ((this.caption) && (this.photo[this.current].a)) {
			this.slider.text.innerHTML = this.photo[this.current].a;
			Element.show(this.slider.caption);
		}
		setTimeout(this.loadNext.bind(this), 200);
		if (!this.paused) this.updateSpeed();
	},

	loadNext: function(e) {
		var nextid = this.getPhotoCurrentId(this.current+1);
		if (!this.photo[nextid].im) {
			this.photo[nextid].im = new Image;
			this.photo[nextid].im.src = this.album.link+"v/"+this.photo[nextid].i+".jpg";
		}
	},

	onLoadImg: function(e) {
		setTimeout(this.showPhoto.bind(this), 200);
	},

	go: function(id) {
		if (!(this.initialized)) return;
		if (!(this.started)) this.start();

		Element.hide(this.slider.caption);
		Element.hide(this.slider.img);

		this.current = this.getPhotoCurrentId(id);
		var dim = this.getPhotoDimensions(this.current);

		if (this.photo[this.current].im) {
			this.slider.img.src = this.photo[this.current].im.src;
		} else {
			Element.show(this.slider.load);
			this.slider.img.src = this.album.link+"v/"+this.photo[this.current].i+".jpg";
			this.photo[this.current].im = new Image;
			this.photo[this.current].im.src = this.slider.img.src;
		}
		Element.setStyle(this.slider.img, dim);
	},

	goNext: function() {
		this.go(this.current+1);
	},

	goPrev: function() {
		this.go(this.current-1);
	},

	getOpacity: function(val) {
		if (is_ie) return {opacity: val, filter: "alpha(opacity="+(val*100)+")"};
		return {opacity: val};
	},

	opacityNav: function(event) {
		if (this.btnhide_timer) clearInterval(this.btnhide_timer);
		this.btnhide_timer = null;

		var val = Element.getStyle(this.slider.nav, "opacity");
		if (val > 0) {
			val = val - 0.05;
			Element.setStyle(this.slider.nav, this.getOpacity(val));
			this.btnhide_timer = setInterval(this.opacityNav.bind(this), 20);
		}
	},

	hideBtn: function(event) {
		if (this.btnhide_timer) clearInterval(this.btnhide_timer);
		this.btnhide_timer = setInterval(this.opacityNav.bind(this), 100);
	},

	showNav: function(event) {
		if (this.btnhide_timer) clearInterval(this.btnhide_timer);
		this.btnhide_timer = null;

		if (this.btn_timer) clearInterval(this.btn_timer);
		this.btn_timer = setInterval(this.hideBtn.bind(this), 2000);
		Element.setStyle(this.slider.nav, this.getOpacity(0.7));
	},

	keyPress: function(event) {
		if (event.keyCode == Event.KEY_ESC) {
			if (this.paused) this.stop()
			else {
				this.showNav();
				setTimeout(this.pause.bind(this), 200);
			}
		}
		else if (event.keyCode == Event.KEY_RETURN) {
			this.showNav();
			if (this.paused) setTimeout(this.play.bind(this), 200);
		}
		else if ((event.keyCode == Event.KEY_LEFT) || (event.keyCode == Event.KEY_PGUP)) this.goPrev()
		else if ((event.keyCode == Event.KEY_SPACE) || (event.keyCode == Event.KEY_RIGHT) || (event.keyCode == Event.KEY_PGDOWN)) this.goNext()
		else return;
		Event.stop(event);
	},

	mouseMove: function(event) {
		this.showNav();
		var handle = Event.element(event);
		if ((!/nav_pause$/.test(handle.id)) && (!/_n\./.test(this.slider.navbtn.pause.src)))
			this.slider.navbtn.pause.src = this.paused ? this.nav_btn.play_n.src : this.nav_btn.pause_n.src;
	},

	start: function() {
		if (!(this.initialized)) return;
		if (this.started) return;
		this.started = true;
		this.current = this.begin;

		document.body.style.background = this.background;
		for (var n = document.body.firstChild; n != null; n = n.nextSibling) {
			if (n.style && n.style.display == "") {
				Element.addClassName(n, "sliderhide");
				n.style.display = "none";
			}
		}

		if ((!this.body.width) || (!this.body.height)) {
		    var divTest = document.createElement('div');
		    Element.setStyle(divTest, {width:"100%", height:"100%"});
		    document.body.appendChild(divTest);
			this.body.width = divTest.offsetWidth || 500;
			this.body.height = divTest.offsetHeight || 500;
			divTest.parentNode.removeChild(divTest);

			this.maxWidth = this.body.width;
			this.maxHeight = this.body.height-5;
		}

		if (!$('slider_div')) {
			new Insertion.Bottom(document.body, this.getPhotoDiv());
			this.slider = {
				div: $('slider_div'), img: $('slider_img'), caption: $('slider_caption'), text: $('slider_text'), nav: $('slider_nav'), load: $('slider_load'), speed: $('slider_speed'),
				navbtn: {
					prev: $('slider_nav_prev'), next: $('slider_nav_next'), pause: $('slider_nav_pause'), minus: $('slider_nav_minus'), plus: $('slider_nav_plus'), stop: $('slider_nav_stop'),
					caption: $('slider_nav_caption')
				}
			};

			if ((this.caption) && (this.photo[this.current].a)) Element.show(this.slider.caption)
			else Element.hide(this.slider.caption);

			Event.observe(this.slider.img, "load", this.onLoadImg.bindAsEventListener(this));

			this.slider.navbtn.prev.src = this.nav_btn.prev_n.src;
			Event.observe(this.slider.navbtn.prev, "click", this.goPrev.bindAsEventListener(this));
			Event.observe(this.slider.navbtn.prev, "mouseover", this.setPrevOver.bindAsEventListener(this));
			Event.observe(this.slider.navbtn.prev, "mouseout", this.setPrevOut.bindAsEventListener(this));

			this.slider.navbtn.next.src = this.nav_btn.next_n.src;
			Event.observe(this.slider.navbtn.next, "click", this.goNext.bindAsEventListener(this));
			Event.observe(this.slider.navbtn.next, "mouseover", this.setNextOver.bindAsEventListener(this));
			Event.observe(this.slider.navbtn.next, "mouseout", this.setNextOut.bindAsEventListener(this));

			this.slider.navbtn.pause.src = this.nav_btn.pause_n.src;
			this.eventPause = this.pause.bindAsEventListener(this);
			Event.observe(this.slider.navbtn.pause, "click", this.eventPause);
			Event.observe(this.slider.navbtn.pause, "mouseover", this.setPauseOver.bindAsEventListener(this));
			Event.observe(this.slider.navbtn.pause, "mouseout", this.setPauseOut.bindAsEventListener(this));

			this.eventPlay = this.play.bindAsEventListener(this);

			this.eventSpeed = this.setSpeed.bindAsEventListener(this);
			this.slider.navbtn.minus.src = this.nav_btn.minus.src;
			Event.observe(this.slider.navbtn.minus, "click", this.eventSpeed);
			this.slider.navbtn.plus.src = this.nav_btn.plus.src;
			Event.observe(this.slider.navbtn.plus, "click", this.eventSpeed);

			this.slider.navbtn.stop.src = this.nav_btn.stop.src;
			Event.observe(this.slider.navbtn.stop, "click", this.stop.bindAsEventListener(this));

			Event.observe(this.slider.navbtn.caption, "click", this.toggleCaption.bindAsEventListener(this));
		}

		if (!this.eventKeypress) this.eventKeypress = this.keyPress.bindAsEventListener(this);
		if (!this.eventMouseMove) this.eventMouseMove = this.mouseMove.bindAsEventListener(this);

		Event.observe(document, "keypress", this.eventKeypress);
		Event.observe(document, "mousemove", this.eventMouseMove);
		Event.observe(document, "click", this.eventKeypress);
		this.showNav();

		this.updateSpeed();
	},

	// btn
	setPrevOver: function() {
		this.slider.navbtn.prev.src = this.nav_btn.prev.src;
	},

	setPrevOut: function() {
		this.slider.navbtn.prev.src = this.nav_btn.prev_n.src;
	},

	setNextOver: function() {
		this.slider.navbtn.next.src = this.nav_btn.next.src;
	},

	setNextOut: function() {
		this.slider.navbtn.next.src = this.nav_btn.next_n.src;
	},

	setPauseOver: function() {
		this.slider.navbtn.pause.src = this.paused ? this.nav_btn.play.src : this.nav_btn.pause.src;
	},

	setPauseOut: function() {
		this.slider.navbtn.pause.src = this.paused ? this.nav_btn.play_n.src : this.nav_btn.pause_n.src;
	},


	getHTMLCaption: function() {
		return this.caption ? 'скрыть подписи' : 'показать подписи';
	},

	toggleCaption: function(event) {
		this.caption = !this.caption;
		this.showNav();
		this.slider.navbtn.caption.innerHTML = this.getHTMLCaption();
		if (this.caption) Element.show(this.slider.caption)
		else Element.hide(this.slider.caption);
	},

	setSpeed: function(event) {
		var handle = Event.element(event);
		if (/plus$/.test(handle.id)) this.updateSpeed(this.speed+1)
		else this.updateSpeed(this.speed-1);
		this.showNav();
		this.slider.speed.innerHTML = this.speed;
	},

	updateSpeed: function(val) {
		if (val) this.speed = parseInt(val);
		if (this.speed < 1) this.speed = 1;
		if (this.speed > 30) this.speed = 30;
		if (this.timer) clearInterval(this.timer);
		this.timer = setInterval(this.goNext.bind(this), this.speed * 1000);
	},

	pause: function() {
		this.paused = true;
		if (this.timer) clearInterval(this.timer);
		this.timer = null;

		Event.stopObserving(this.slider.navbtn.pause, "click", this.eventPause);
		this.slider.navbtn.pause.src = this.nav_btn.play.src;
		Event.observe(this.slider.navbtn.pause, "click", this.eventPlay);
	},

	play: function() {
		Event.stopObserving(this.slider.navbtn.pause, "click", this.eventPlay);
		this.slider.navbtn.pause.src = this.nav_btn.pause.src;
		Event.observe(this.slider.navbtn.pause, "click", this.eventPause);

		this.updateSpeed();
		this.paused = false;
	},

	stop: function() {
		if (!(this.initialized)) return;
		if (!(this.started)) return;

		this.pause();
		clearInterval(this.btn_timer); this.btn_timer = null;
		Event.stopObserving(document, "mousemove", this.eventMouseMove);
		Event.stopObserving(document, "keypress", this.eventKeypress);
		Event.stopObserving(document, "click", this.eventKeypress);

		document.body.style.background = this.body.background;
		for (var n = document.body.firstChild; n != null; n = n.nextSibling) {
			if (n.style && n.style.display == "none") {
				n.style.display = "";
				if (Element.hasClassName(n, "sliderhide")) Element.removeClassName(n, "sliderhide");
				else n.style.display = "none";
			}
		}
		this.slider.div.parentNode.removeChild(this.slider.div);
		this.slider.div = false;
		this.started = false;
	}
}

