/**
 * @author VasiliyK
 */
 
 (function ($) {
	
	var index = 0;
	FOCUSED = 1;
	BLURED = 2;
	var status = BLURED;
	var currentPage = 1;
	var elementClass = "element";
	var mainClass = "imageView";
	var cols = 6;
	var rows = 2;
	var pageSize = 18;
	var moveUpCallback;
	var moveDownCallback;
	var pageChangedCallback;
	var totalElements = 0;
	var imageUrlPattern = null;
	var patternFields = null;
	
	$.fn.ImageView = function (data, options) {
		if (!$(this).data("sfui")) {
			$(this).data("sfui", "ImageViewer");
		}
		
		if (typeof(data) === "object") {
			init($(this), data);
		} else if (typeof(data) === "string") {
			switch (data) {
				case "moveLeft":
					moveLeft($(this));
					break;
				case "moveRight":
					moveRight($(this));
					break;
				case "moveDown":
					moveDown($(this));
					break;
				case "moveUp":
					moveUp($(this));
					break;
				case "move":
					if (!options) {
						return;
					}
					move($(this), options);
					break;
				case "focus":
					focus($(this));
					break;
				case "blur":
					blur($(this));
					break;
				case "clear":
					deinit($(this));
					break;
				case "getIndex":
					return getIndex($(this));
					break;
			}
		}
		
		return $(this);
	}
	
	function init(self, data) {
		if (!self || !data || typeof(data) !== "object") {
			return;
		}
		
		elementClass = data.elementClass || elementClass;
		mainClass = data.mainClass || mainClass;
		cols = data.cols || cols;
		rows = data.rows || rows;
		pageSize = cols * rows;
		moveUpCallback = data.moveUpCallback;
		moveDownCallback = data.moveDownCallback;
		pageChangedCallback = data.pageChangedCallback;
		imageUrlPattern = data.imageUrlPattern || null;
		patternFields = data.patternFields;
		
		$(self).empty();
		
		if (!$(self).hasClass(mainClass)) {
			$(self).addClass(mainClass);
		}
		if (data.elements && data.elements.length > 0) {
			$("<div>").addClass("slider").appendTo($(self));
			var container = $(self).find(".slider");
			$(data.elements).each(function (idx) {
				var imgDiv = $("<div>").addClass("image");
				var imageUrl = this.imageUrl;
				if (imageUrlPattern && patternFields && patternFields.length) {
					patternUrl = imageUrlPattern;
					for (var i = 0; i < patternFields.length; i++) {
						patternUrl = patternUrl.replace("{" + i + "}", this[patternFields[i]]);
					}
					imageUrl = patternUrl
				}
				$("<img>").attr("src", imageUrl).appendTo($(imgDiv));
				var text = $("<div>").html(this.name).addClass("name");
				var border = $("<div>").addClass("border");
				$("<div>").attr("data-id", this.id).addClass(elementClass).append($(imgDiv)).append($(text)).append($(border)).appendTo($(container));
			});
			
			$(container).children().first().addClass("selected");
			index = 0;
			currentPage = 1;
			totalElements = data.elements.length;
		}
	}
	
	function deinit(self) {
		if (self) {
			$(self).empty();
		}
		
		index = 0;
		status = BLURED;
		currentPage = 0;
		elementClass = "element";
		mainClass = "imageView";
		totalElements = 0;
		moveUpCallback = null;
		moveDownCallback = null;
		pageChangedCallback = null;
		imageUrlPattern = null;
		patternFields = null;
	}
	
	function focus(self) {
		if (status === BLURED) {
			$(self).find(".slider").children(".selected").removeClass("selected").addClass("focused");
			$(self).addClass("focused");
			status = FOCUSED;
		}
	}
	
	function blur(self) {
		if (status === FOCUSED) {
			$(self).find(".slider").children(".focused").removeClass("focused").addClass("selected");
			$(self).removeClass("focused");
			status = BLURED;
		}
	}
	
	function move(self, idx) {
		if (idx < 0) {
			if (moveUpCallback) {
				moveUpCallback();
			}
			return;
		}
		
		if (idx >= totalElements) {
			if (moveDownCallback) {
				moveDownCallback();
			}
			return;
		}
		
		if (status === BLURED) {
			$(self).find(".slider").find(".selected").removeClass("selected");
			$(self).find(".slider").children().eq(idx).addClass("selected");
		} else if (status === FOCUSED) {
			$(self).find(".slider").children(".focused").removeClass("focused");
			$(self).find(".slider").children().eq(idx).addClass("focused");
		}
		
		index = idx;
		
		var newPage = Math.ceil((index + 1) / pageSize);
		if (newPage != currentPage) {
			showPage($(self), newPage);
		}
	}
	
	function showPage(self, page) {
		var totalElementHeight = $(".element").height() + parseInt($(".element").css("margin-top")) + parseInt($(".element").css("margin-bottom"));
		var height = totalElementHeight * rows;
		
		height = (-height) * (page - 1);
		$(self).children(".slider").css({'top': height + "px"});
		
		if (currentPage != page) {
			if (pageChangedCallback) {
				pageChangedCallback(page);
			}
			
			currentPage = page;
		}
	}
	
	function getIndex(self) {
		return index;
	}
	
	function moveLeft(self) {
		move(self, index - 1);
	}
	
	function moveRight(self) {
		move(self, index + 1);
	}
	
	function moveUp(self) {
		move(self, index - cols);
	}
	
	function moveDown(self) {
		var row = Math.ceil((index + 1)/cols);
		var totalRows = Math.ceil(totalElements / cols);
		var idx = index + cols;
		if ((index + cols >= totalElements) && row < totalRows) {
			idx = totalElements - 1;
		}
		move(self, idx);
	}
 })(jQuery);