var PhotoScroller = function (element) {
	var	T = this,
		container = $(element),
		viewport = $(".viewport", container),
		frames = $(".frames", viewport),
		cache = [],
		controls = {
			prev: $(".prev", container),
			next: $(".next", container)
		},
		currentFrame = -1,
		galleryData = [],
		params = {
			loadedAttr: "psc-loaded",
			galleryDataURL: "exturl",
			lastHashFragment: "/photodetail/",
			slideWidth: 600,
			slideHeight: 600,
			animTime: 300
		},
		animating = false;
	
	function loadGalleryData (url, callback) {
		$.get(url, function (data) {
			callback.call(T, eval(data));
		});
	}
	
	function afterInit(data) {
		var width = params.slideWidth,
			height = params.slideHeight,
			currentFrameId = null;
		
		var parts = /\/(\d+)$/.exec(location.hash.toString());
		currentFrameId = parts[1];

		// устанавливаем данные для галареи
		galleryData = data;
		fillFramesCache();
		
		// фиксируем размеры окна просмотра
		viewport.css({
			"height": height,
			"overflow": "hidden",
			"position": "relative",
			"width": width
		});
		
		frames.css({
			"height": height,
			"position": "absolute",
			"top": 0,
			"width": width
		});
		
		var framesContent = document.createDocumentFragment();
		
		var createSpike = function (img, frame) {
			return function () {
				frame.setAttribute("spiked", true);
				frame.style.top = (height - img.height) / 2 + "px";
				frame.style.marginLeft = (width - img.width) / 2 + "px";
			}
		}
		
		for (var i = 0, l = galleryData.length; i < l; ++i) {
			var frame = document.createElement("div");
			var img = document.createElement("img");
			var item = galleryData[i];
			img.className = "puke";
			img.src = item.src;
			img.width = item.width || "";
			img.height = item.height || "";
			frame.style.position = "absolute";
			frame.style.textAlign = "left";
			frame.style.top = "0";
			frame.style.width = width + "px";
			frame.style.height = height + "px";
			frame.style.left = params.slideWidth * i + "px";
			frame.appendChild(img);
			
			framesContent.appendChild(frame);
			var spike = createSpike(img, frame);
			$(img).bind("load", spike);
			if (img.complete) {
				setTimeout(spike, 0);
				//spike();
			}
		}
		
		frames[0].innerHTML = "";
		frames[0].appendChild(framesContent);
		
		var decorator = new DolinaImageDecorator("/i/puke.png", 17, 12);
		
		// я хрен знаю что происходит тут с ИЕ, но без таймаута не работает
		setTimeout(function(){
			$("img", frames).each(function () {
				decorator.decorate(this);
				//console.log(this);
			});
		}, 0)
		
		var frameNum = getFrameIndexById(currentFrameId);
		
		showFrame(frameNum, true);
		
		controls.prev.bind("click", function (e) {
			e.preventDefault();
			prev();
		}).show();
		controls.next.bind("click", function (e) {
			e.preventDefault();
			next();
		}).show();
	}
	
	function fillFramesCache() {
		for (var i = 0, l = galleryData.length; i < l; ++i) {
			cache[galleryData[i].id] = i;
		}
	}
	
	function getFrameIndexById(id) {
		return cache[id];
	}
	
	function showFrame(x, noanim) {
		var min = 0, max = galleryData.length - 1;
		
		if (x < min) {
			x = min;
		}
		
		if (x > max) {
			x = max;
		}
		
		currentFrame = x;
		frames.stop();
		
		if (!noanim) {
			animating = true;
			frames.animate({
				left: -x * params.slideWidth
			}, params.animTime, function () {
				animating = false;
			});
		} else {
			frames.css({
				left: -x * params.slideWidth
			});
		}
		
		if (x == min) {
			controls.prev.hide();
		} else {
			controls.prev.show();
		}
		
		if (x == max) {
			controls.next.hide();
		} else {
			controls.next.show();
		}
	}
	
	function next() {
		showFrame(currentFrame + 1);
	}
	
	function prev() {
		showFrame(currentFrame - 1);
	}
	
	function init () {
		container.attr(params.loadedAttr, "true");
		var galleryDataURL;

		if (galleryDataURL = container.attr(params.galleryDataURL)) {
			galleryData = loadGalleryData(galleryDataURL, function (data) {
				afterInit(data);
			});
		}
		controls.prev.hide();
		controls.next.hide();
	};
	
	if (container.attr(params.loadedAttr) == "true") {
		
	} else {
		init();
	}
}
