SHP = window.SHP || {};

// Widget manager container
(function(window, undefined){
	
	// Prevent multiple container declarations
	if (SHP.WidgetManager) {
		return;
	}
	
	// Get all script tags
	var shp_scripts = document.getElementsByTagName("script");
	
	// Extract directory of the last script tag
	SHP.shp_scripts_dir = shp_scripts[shp_scripts.length - 1].src.split("?")[0].split("/").slice(0, -1).join("/");
	// Loader images
	SHP.ajax_loader = "<img src=\"" + SHP.shp_scripts_dir + "/../../img/widget/ajax_loader.gif\" style=\"width: 66px; height: 66px; vertical-align: top;\" />";
	SHP.ajax_content_loader = "<div style=\"position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-color: #FFFFFF;  -moz-opacity:.80; filter:alpha(opacity=80); opacity:.80;\">&nbsp;</div><img src=\"" + SHP.shp_scripts_dir + "/../../img/widget/ajax_loader.gif\" style=\"position: absolute; top: 50%; left: 50%; width: 66px; height: 66px; margin-top: -33px; margin-left: -33px; vertical-align: top;\" />";

	// Ucfirst functions
	SHP.ucfirst = function(str) {
		str += "";
		var f = str.charAt(0).toUpperCase();
		return f + str.substr(1);
	};
	
	// Invert color
	SHP.invertColor = function(hex1, hex2) {
		if (hex1.toLowerCase() != hex2.toLowerCase()) {
			return hex1;
		}
		
		if (hex1.indexOf("#") !== 0) {
			return hex1;
		}
		
		hex1 = hex1.substr(hex1.indexOf("#") + 1);
		
		var h1 = hex1.slice(0,2);
		var h2 = hex1.slice(2,4);
		var h3 = hex1.slice(4,6);
		
		return "rgb(" + (255 - parseInt(h1, 16)) + ", " + (255 - parseInt(h2, 16)) + ", " + (255 - parseInt(h3, 16)) + ")";
	};
	
	// Widget manager constructor
	SHP.WidgetManager = function(type, opt) {
		this.init(type, opt);
	};
	
	// Global vars
	SHP.WidgetManager.jq_loading = false;
	SHP.WidgetManager.ready_list = [];
	SHP.WidgetManager.widgets = {};
	SHP.WidgetManager.widget_cnt = 0;
	SHP.WidgetManager.widget_list = {};
	
	// Widget manager prototype
	SHP.WidgetManager.prototype = function(){
		
		return {
			// Possible widgets
			widgets: {
				ministore: 1,
				offers: 1
			},
			// Init function
			init: function(opt) {
			
				opt = opt || {};
				opt.cnt = ++ SHP.WidgetManager.widget_cnt;
				
				// Error message
				if (this.widgets[opt.widget] == undefined) {
					document.write("<p style=\"color: #CC0000;\">Invalid widget type</p>");
					return;
				}
				
				if (!SHP.WidgetManager.widgets[opt.widget]) {
					SHP.WidgetManager.widgets[opt.widget] = {css_loading: false, css_ready_list: []};
				}
				
				// Write widget container
				document.write("<div id=\"shp_" + opt.widget + "_" + opt.cnt + "\" class=\"shp_" + opt.widget + "\">" + SHP.ajax_loader + "</div>");
				
				// Done jQuery loading
				if (SHP.WidgetManager.jq_loading == "done") {
					this._execWidgetContainer(opt);
				}
				else {
					// Push winget to ready list if jQuery not loaded
					SHP.WidgetManager.ready_list.push(opt);
					
					if (!SHP.WidgetManager.jq_loading) {
						SHP.WidgetManager.jq_loading = "init";
						var jq_url = SHP.shp_scripts_dir + "/shp_jq.js";
						this._loadScript(jq_url, this._doneJqLoading);
					}
				}
			},
			// Load external script
			_loadScript: function(url, callback) {
				var self = this;
				var script = document.createElement("script");
				script.type = "text/javascript";
				
				if (script.readyState) {  //IE
					script.onreadystatechange = function(){
						if ( (script.readyState == "loaded") || (script.readyState == "complete") ) {
							script.onreadystatechange = null;
							if (typeof(callback) == "function") {
								callback.call(self);
							}
						}
					};
				}
				else {  //Others
					script.onload = function(){
						if (typeof(callback) == "function") {
							callback.call(self);
						}
					};
				}

				script.src = url;
				document.getElementsByTagName("head")[0].appendChild(script);
			},
			// Done jQuery loading
			_doneJqLoading: function() {
				SHP.WidgetManager.jq_loading = "done";
				
				// Execute all of them
				var obj, i = 0;
				while (obj = SHP.WidgetManager.ready_list[i ++]) {
					this._execWidgetContainer(obj);
				}
			},
			// Run widget container and create new widget
			_execWidgetContainer: function(obj) {
				SHP['widget_container_' + obj.widget].call(this, shp_jq);
				var w = new SHP['Widget' + SHP.ucfirst(obj.widget)](obj);
				SHP.WidgetManager.widget_list[obj.widget] = SHP.WidgetManager.widget_list[obj.widget] || [];
				SHP.WidgetManager.widget_list[obj.widget].push(w);
			}
		}
	}();
	
})(window);

// Widget container (executed only after jquery loads)
SHP.widget_container_ministore = function($, undefined) {
	
	if (!SHP.WidgetBase) {
		// Base widget class (common for all widgets)
		SHP.WidgetBase = function() {
			
			// Load config method
			this._loadConfig = function() {
							
				// Pause other actions
				this.loading = true;
				
				// Load config data from remote
				$.ajax($.extend(true, {}, {
					url: this.cfg.remote_path + "?request=" + this.cfg.config_request + "&obj=" + this.opt.obj + "&lw_url=" + document.location + "&linktagging=" + this.opt.linktagging,
					dataType: "jsonp",
					context: this,
					success: function(data) {
						
						// Maintenance
						if (data.status == "maintenance") {
							this.el.html("<p style=\"color: #999999;\">Please try again later</p>");
							return false;
						}
						// Resume pending actions
						this.loading = false;
						
						// Extend config with new data
						this.cfg = $.extend(true, {}, this.cfg, data);
						this.cfg = $.extend(true, {}, this.cfg, this.opt.lang);
						
						// Load stylesheets
						this._loadStyleSheets();
					}
				}, (($.browser.msie && $.browser.version.substr(0,1) < 8) ? {} : {jsonpCallback: "jsonpConfigCallback_" + this.opt.obj})));
			};
			
			// Load stylesheets method
			this._loadStyleSheets = function() {
				var self = this;
				
				// If css already loaded, draw widget
				if (SHP.WidgetManager.widgets[this.cfg.widget].css_loading == "done") {
					self._drawWidget();
				}
				else {
					// Push widget into the ready list
					SHP.WidgetManager.widgets[this.cfg.widget].css_ready_list.push(this);
					
					// Load only once
					if (!$("#shp_widget_" + self.cfg.widget + "_css").length) {
						
						if (document.createStyleSheet) {
							document.createStyleSheet(SHP.shp_scripts_dir + "/../../css/widget/widget_" + self.cfg.widget + ".css");
						}
						else {
							// Create new stylesheet tag in head
							$("<link>", {
								"id": "shp_widget_" + self.cfg.widget + "_css",
								"rel": "stylesheet",
								"type": "text/css",
								"href": SHP.shp_scripts_dir + "/../../css/widget/widget_" + self.cfg.widget + ".css"
							}).appendTo("head");
						}
						
						// Check every 50 miliseconds if stylesheet was loaded
						var j = setInterval(function () {
							if (self.el.css("position") == "relative") {
								// Clear and garbagecollect the interval
								clearInterval(j);
								j = null;
								
								// Load callback
								self._doneStyleSheetsLoading();
							}
						}, 50);
					}
				}
			};
			
			// Draw all widgets from css ready list
			this._doneStyleSheetsLoading = function() {
				
				// Mark css as loaded
				SHP.WidgetManager.widgets[this.cfg.widget].css_loading = "done";
				
				// Execute all of them
				var obj, i = 0;
				while (obj = SHP.WidgetManager.widgets[this.cfg.widget].css_ready_list[i ++]) {
					obj._drawWidget();
					obj.widget_loading = false;
				}
			};
		}
	}
	
	// Prevent multiple widget declarations
	if (SHP.WidgetMinistore) {
		return;
	}
	
	// Ministore widget class
	SHP.WidgetMinistore = function(opt) {
		
		// Initial config
		this.cfg = {
			remote_path: "http://" + opt.domain + "/remote_connector",
			config_request: "ministore_config",
			widget: "ministore",
			back_history: 10,
			show_new: 1,
			show_deals: 1
		};
		
		// Widget states
		this.state = {
			cat: 0,
			last_cat: 0,
			cat_loaded: 0,
			list_title: "",
			display_mode: "list",
			list_start: 0,
			view_start: 0
		};
		
		this.state_arr = [];
		
		// Default options
		this.default_opt = {
			step: 6,
			rowitems: 2,
			width: 340,
			height: "auto",
			roundedcorners: 1,
			linktagging: 1,
			listmode: "full",
			theme: {
				shell: {
					background: '#8EC1DA',
					color: '#FFFFFF'
				},
				content: {
					background: '#FFFFFF',
					color: '#444444',
					links: '#1985B5',
					price: '#ED1C24'
				}
			}
		};
		
		this.loading = false;
		this.widget_loading = true;
		
		// Init function
		this.init = function(opt) {
			
			// Store widget dom
			this.el = $("#shp_" + this.cfg.widget + "_" + opt.cnt);
			
			// Required widget mode
			if (!opt.domain) {
				this.el.html("<p style=\"color: #CC0000;\">Undefined widget domain</p>");
				return;
			}
			
			// Required object key
			if (!(opt.obj > 0)) {
				this.el.html("<p style=\"color: #CC0000;\">Invalid object key</p>");
				return;
			}
			
			// Extend default options
			this.opt = $.extend(true, {}, this.default_opt, opt);
			
			// Load config and init widget
			this._loadConfig.call(this);
		};
		
		// Rebuild widget
		this._redrawWidget = function(opt) {
			
			// Extend default options
			$.extend(true, this.opt, opt);
			
			this.state.cat_loaded = 0;
			for (var i = 0; i < this.state_arr.length; i ++) {
				this.state_arr[i].cat_loaded = 0;
			}
			
			if (!this.widget_loading) {
				this._drawWidget();
			}
		}
		
		// Start building the widget
		this._drawWidget = function() {
			// Add link tagging
			this.cfg.link_tagging = (this.opt.linktagging > 0 ? ("?utm_source=shopmania_widgets&utm_medium=web&utm_content=" + (typeof(document.domain) != "undefined" ? encodeURI(document.domain.replace(/^www\./, "")) : "minishop")) : "");
			
			this.el.css({visibility: "hidden"});
			
			// Set initial list title
			this.state.list_title = this.cfg.lang_prod_all;
			
			// Set widget dimensions
			var str_width = new String(this.opt.width);
			if (this.opt.width > 0) {
				this.el.width(this.opt.width);
			}
			if (str_width.toLowerCase() == "auto") {
				this.el.css({width: "auto"});
				this.el.width(this.el.innerWidth());
			}
			if (this.opt.height > 0) {
				this.el.height(this.opt.height);
			}
			
			// Assign new styles
			this.el.css({color : SHP.invertColor(this.opt.theme.shell.color, this.opt.theme.shell.background)});
			this.el.css({backgroundColor : this.opt.theme.shell.background});
			
			// Add / remove rounded corners to container
			this.el[(this.opt.roundedcorners ? "add" : "remove") + 'Class']("shp_ministore_border_radius");
			
			// Build widget frame and rewrite some css
			this.el.html("<style type=\"text/css\">" +
					"#shp_" + this.cfg.widget + "_" + this.opt.cnt + " a {color: " + SHP.invertColor(this.opt.theme.shell.color, this.opt.theme.shell.background) + "; outline: none; background-color: transparent; border: none;}\n" +
					"#shp_" + this.cfg.widget + "_" + this.opt.cnt + " .bd a {color: " + SHP.invertColor(this.opt.theme.content.links, this.opt.theme.content.background) + ";}\n" +
					"#shp_" + this.cfg.widget + "_" + this.opt.cnt + " .list li {width: " + (100 / this.opt.rowitems - (this.opt.listmode == "photo" ? 0 : 2)) + "%; padding-right: " + (this.opt.listmode == "photo" ? "0" : "2") + "%;}\n" +
					"#shp_" + this.cfg.widget + "_" + this.opt.cnt + " .prod_price {color: " + SHP.invertColor(this.opt.theme.content.price, this.opt.theme.content.background) + ";}\n" +
					"#shp_" + this.cfg.widget + "_" + this.opt.cnt + " .prod_view .prod_cat a {color: " + SHP.invertColor(this.opt.theme.content.color, this.opt.theme.content.background) + ";}\n" +
				"</style>" +
				"<div class=\"hd cfix\">" +
					(this.cfg.store_logo ? "<a href=\"" + this.cfg.store_url + "\" target=\"_blank\" class=\"store_logo\"><img src=\"" + this.cfg.store_logo + "\" alt=\"" + this.cfg.store_name + "\" /></a>" : "") +
					"<a href=\"" + this.cfg.store_url + "\" target=\"_blank\" class=\"store_name\">" + this.cfg.store_name + "</a>" +
				"</div>" +
				"<div class=\"bd cfix " + (this.opt.roundedcorners ? "shp_ministore_border_radius" : "") + "\">" +
					"<div class=\"nav cfix\">" +
						"<span class=\"page_nr\"></span>" +
						"<a href=\"#\" class=\"nav_back png\" title=\"" + this.cfg.lang_prod_back + "\" style=\"display: none;\">&nbsp;</a>" +
						"<a href=\"#\" class=\"nav_cat png\" title=\"" + this.cfg.lang_prod_cat + "\">&nbsp;</a> " +
						"<a href=\"#\" class=\"nav_list png\" title=\"" + this.cfg.lang_prod_all + "\">&nbsp;</a> " +
						(!this.cfg.show_deals ? "" : "<a href=\"#\" class=\"nav_deals png\" title=\"" + this.cfg.lang_prod_deals + "\">&nbsp;</a> ") +
						(!this.cfg.show_new ? "" : "<a href=\"#\" class=\"nav_new png\" title=\"" + this.cfg.lang_prod_new + "\">&nbsp;</a> ") +
						"<a href=\"#\" class=\"nav_prev png\" title=\"" + this.cfg.lang_prod_prev + "\">&nbsp;</a> " +
						"<a href=\"#\" class=\"nav_next png\" title=\"" + this.cfg.lang_prod_next + "\">&nbsp;</a>" +
					"</div>" +
					"<div class=\"wrapper\">" +
						"<div class=\"dat cfix\">" +
							"<div class=\"cat\">" + SHP.ajax_content_loader + "</div>" +
							"<div class=\"list\">" + SHP.ajax_content_loader + "</div>" +
							"<div class=\"view\">" + SHP.ajax_content_loader + "</div>" +
						"</div>" +
					"</div>" +
				"</div>" +
				"<div class=\"ft cfix\">" + (this.el.next(".shopmania_powered").length ? this.el.next(".shopmania_powered").html() : this.cfg.link_powered) + "</div>");
				this.el.next(".shopmania_powered").remove();
				// <a href=\"http://www.shopmaniaro.asesoftnet.com/widgets\" target=\"_blank\" class=\"link_widgets\">[+] Widgets</a>
			
			// Store widget dom sections
			this.hd = this.el.find("div.hd");
			this.bd = this.el.find("div.bd");
			this.ft = this.el.find("div.ft");
			
			this.nav = this.bd.find("div.nav");
			this.wrapper = this.bd.find("div.wrapper");
			this.dat = this.wrapper.find("div.dat");
			this.list = this.dat.find("div.list");
			this.view = this.dat.find("div.view");
			this.cat = this.bd.find("div.cat");
			
			// Store reference (used in delegate function)
			var self = this;
			
			if (this.cfg.store_logo && (this.opt.height > 0) ) {
				
				this.el.find("a.store_logo img").bind("load", function(){
					var new_height = self.opt.height - self.hd.outerHeight(true) - self.nav.outerHeight(true) - self.ft.outerHeight(true)
					self.cat.height(new_height);
					self.list.height(new_height);
					self.view.height(new_height);
				});
			}
			
			this.bd.css({color : SHP.invertColor(this.opt.theme.content.color, this.opt.theme.content.background)});
			this.bd.css({backgroundColor : this.opt.theme.content.background});
			
			// Rewrite width in pixels (to avoid animation bugs in webkit and opera)
			var new_width = this.wrapper.width();
			this.dat.width(3 * new_width);
			this.cat.width(new_width);
			this.list.width(new_width);
			this.view.width(new_width);
			
			var offset;
			if (this.state.display_mode  == "list") {
				offset = "-" + new_width;
			}
			else if (this.state.display_mode  == "cat") {
				offset = 0;
			}
			else if (this.state.display_mode  == "view") {
				offset = "-" + 2 * new_width;
			}
			
			this.dat.css({left: offset + "px"});
			
			// Force height
			if (this.opt.height > 0) {
				var new_height = this.opt.height - this.hd.outerHeight(true) - this.nav.outerHeight(true) - this.ft.outerHeight(true)
				this.cat.height(new_height);
				this.list.height(new_height);
				this.view.height(new_height);
			}
			
			// Delegate events to nav and list containers
			this.cat.undelegate().delegate("a", "click", function(e) {
				
				// Ignore action if page is loading
				if (self.loading) {
					return false;
				}
				
				self._pushState();
				
				// Cache target
				var $target = $(e.target);
				
				// Refresh 'on' class
				self.cat.find("a").removeClass("on");
				$target.addClass("on");
				
				// Update state
				self.state.last_cat = self.state.cat;
				self.state.cat = $target.data("key");
				self.state.list_title = $target.text();
				self.state.list_start = 0;
				self.state.display_mode = "list";
				
				// Load listign
				self._loadList();
				
				// Toggle view
				self._toggleMode();
				
				return false;
			});
			
			// Delegate events to nav container
			this.nav.undelegate().delegate("a", "click", function(e) {
				
				// Ignore action if page is loading
				if (self.loading) {
					return false;
				}
				
				// Cache target
				var $target = $(e.target);
				
				// Prev button was clicked
				if ($target.is(".nav_prev") && {view: 1, list: 1}[self.state.display_mode]) {
					if (self.state[self.state.display_mode + '_prev']) {
						self._pushState();
					}
					self[self.state.display_mode == "view" ? "_loadView" : "_loadList"](-1);
				}
				// Next button was clicked
				else if ($target.is(".nav_next") && {view: 1, list: 1}[self.state.display_mode]) {
					if (self.state[self.state.display_mode + '_next']) {
						self._pushState();
					}
					self[self.state.display_mode == "view" ? "_loadView" : "_loadList"](1);
				}
				// Category button was clicked
				else if ($target.is(".nav_cat")) {
					self._pushState();
					self.state.display_mode = "cat";
					self._loadCat();
					self._toggleMode();
					self._updateNav.call(self);
				}
				// All products button was clicked
				else if ($target.is(".nav_list")) {
					if ( (self.state.cat != 0) || (!self.list.find("ul").length) ) {
						self._pushState();
					}
					
					self.state.display_mode = "list";
					if ( (self.state.cat != 0) || (!self.list.find("ul").length) ) {
						self.state.list_start = 0;
						self.state.last_cat = self.state.cat;
						self.state.cat = 0;
						self.state.list_title = self.cfg.lang_prod_all;
						self.cat.find("a").removeClass("on");
						
						self._loadList();
					}
					self._toggleMode();
					self._updateNav.call(self);
				}
				// New products button was clicked
				else if ($target.is(".nav_new")) {
					if ( (self.state.cat != "new") || (!self.list.find("ul").length) ) {
						self._pushState();
					}
					self.state.display_mode = "list";
					if ( (self.state.cat != "new") || (!self.list.find("ul").length) ) {
						self.state.list_start = 0;
						self.state.last_cat = self.state.cat;
						self.state.cat = "new";
						self.state.list_title = self.cfg.lang_prod_new;
						self.cat.find("a").removeClass("on");
						
						self._loadList();
					}
					self._toggleMode();
					self._updateNav.call(self);
				}
				// Best deals button was clicked
				else if ($target.is(".nav_deals")) {
					if ( (self.state.cat != "deals") || (!self.list.find("ul").length) ) {
						self._pushState();
					}
					self.state.display_mode = "list";
					if ( (self.state.cat != "deals") || (!self.list.find("ul").length) ) {
						self.state.list_start = 0;
						self.state.last_cat = self.state.cat;
						self.state.cat = "deals";
						self.state.list_title = self.cfg.lang_prod_deals;
						self.cat.find("a").removeClass("on");
						self._loadList();
					}
					self._toggleMode();
					self._updateNav.call(self);
				}
				// Back button was clicked
				else if ($target.is(".nav_back")) {
					if (self.state_arr.length > 0) {
						self.state = self.state_arr.pop();
						self['_load' + SHP.ucfirst(self.state.display_mode)]();
						self._toggleMode();
						self._updateNav.call(self);
					}
				}
				
				return false;
			});
			
			// Delegate events to list container
			this.list.undelegate().delegate("a", "click", function(e) {
			
				// Ignore action if page is loading
				if (self.loading) {
					return false;
				}
				
				self._pushState();
				
				var li = $(this).closest("li");
				self.state.view_start = self.state.list_start + li.closest("ul").find("> li").not(".row_spacer").index(li);
				
				
				self.state.display_mode = "view";
				
				self._loadView();
				self._toggleMode();
				
				return false;
			});
			
			
			this.hd.undelegate().delegate("a.store_logo, a.store_name", "click", function(e) {
				var href = $(this).attr("href");
				var domain = "minishop";
				if (typeof(document.domain) != "undefined") {
					domain = document.domain;
					domain = domain.replace(/^www\./, "");
				}
				href = href.replace("%231%23", escape(domain));
				$(this).attr("href", href);
			});
			
			// Delegate events to view container
			this.view.undelegate().delegate("a.btn_buy, a.prod_thumb, a.prod_name", "click", function(e) {
				var href = $(this).attr("href");
				var domain = "minishop";
				if (typeof(document.domain) != "undefined") {
					domain = document.domain;
					domain = domain.replace(/^www\./, "");
				}
				href = href.replace("%231%23", escape(domain));
				$(this).attr("href", href);
			});
			
			this.view.delegate(".prod_cat a", "click", function(e) {
				
				// Ignore action if page is loading
				if (self.loading) {
					return false;
				}
				
				self._pushState();
				
				// Cache target
				var $target = $(e.target);
				
				// Refresh 'on' class
				self.cat.find("a").removeClass("on");
				self.cat.find("a.cat_" + $target.data("key")).addClass("on");
				
				// Update state
				self.state.last_cat = self.state.cat;
				self.state.cat = $target.data("key");
				self.state.list_title = $target.text();
				self.state.list_start = 0;
				self.state.display_mode = "list";
				
				// Load listign
				self._loadList();
				
				// Toggle view
				self._toggleMode();
				
				return false;
			});
			
			// Load prod list after widget init
			this['_load' + SHP.ucfirst(this.state.display_mode)]();
			this._toggleMode();
			this._updateNav.call(this);
			
			this.el.css({visibility: "visible"});
		};
		
		// Manage state array
		this._pushState = function() {
			this.state_arr.push($.extend(true, {}, this.state));
			
			if (this.state_arr.length > this.cfg.back_history) {
				this.state_arr.splice(0, (this.state_arr.length - this.cfg.back_history));
			}
		}
		
		// Toggle between list, view and cat
		this._toggleMode = function() {
			var wrapper_w = this.wrapper.width();
			// Show listing
			if (this.state.display_mode == "list") {
				if ( (parseFloat(this.dat.css("left")) < - wrapper_w) || (parseFloat(this.dat.css("left")) < wrapper_w) ) {
					this.list.scrollTop(0);
					this.dat.stop(false, false).animate({left: - wrapper_w}, {duration: 500, queue: false});
				}
			}
			// Show product view
			else if (this.state.display_mode == "view") {
				if (parseFloat(this.dat.css("left")) > - (wrapper_w * 2)) {
					this.view.scrollTop(0);
					this.dat.stop(false, false).animate({left: - (wrapper_w * 2)}, {duration: 500, queue: false});
				}
			}
			// Show category listing
			else if (this.state.display_mode == "cat") {
				if (parseFloat(this.dat.css("left")) < 0) {
					this.dat.stop(false, false).animate({left: 0}, {duration: 500, queue: false});
				}
			}
			
			return false;
		};
		
		// Load categories
		this._loadCat = function() {
			
			// Request categories only once
			if (this.state.cat_loaded == 0) {
				$.ajax({
					url: this.cfg.remote_path + "?request=ministore_cat&obj=" + this.opt.obj,
					dataType: "jsonp",
					context: this,
					success: function(data) {
						// Maintenance
						if (data.status == "maintenance") {
							this.el.html("<p style=\"color: #999999;\">Please try again later</p>");
							return false;
						}
						
						this.state.cat_loaded = 1;
						
						// Build categories tree (n levels)
						this.cat.html("<div class=\"cat_title\">" + this.cfg.lang_prod_cat + "</div><ul style=\"zoom: 1;\">" + this._buildCatTree(data) + "</ul>");
					}
				});
			}
		}
		
		// Build category tree
		this._buildCatTree = function(ARR) {
			
			var cat_str = "";
			
			if (typeof(ARR) != "undefined") {
				var l = ARR.length, i = 0;
				
				if (l > 0) {
					for (; i < l; i++) {
						cat_str += "<li><a href=\"#\" class=\"" + (ARR[i].id == this.state.cat ? "on" : "") + " cat_" + ARR[i].id + "\" data-key=\"" + ARR[i].id + "\">" + ARR[i].cat + "</a>";
						
						var KIDS = this._buildCatTree(ARR[i]['KIDS']);
						
						if (KIDS != "") {
							cat_str += "<ul>" + KIDS + "</ul>";
						}
						
						cat_str += "<li>";
					}
				}
			}
			
			return cat_str;
		}
		
		// Load listing
		this._loadList = function(dir) {
			
			if ( (dir == 1 && !this.state.list_next) || (dir == -1 && !this.state.list_prev) || this.loading) {
				return;
			}
			
			this.loading = true;
			
			if (dir == undefined) {
				// Unchange list start
				
				if (this.state.last_cat != this.state.cat) {
					this.list.scrollTop(0).append(SHP.ajax_content_loader);
				}
			}
			else {
				this.list.scrollTop(0).append(SHP.ajax_content_loader);
				
				this.state.list_start = this.state.list_start + dir * this.opt.step;
				this.state.list_start = Math.max(0, this.state.list_start);
			}
			
			// Build url params
			var url_mode_cat = (this.state.cat == "new" ? "&mode=new" : (this.state.cat == "deals" ? "&mode=deals" : (this.state.cat > 0 ? ("&cat=" + this.state.cat) : "")));
			
			// Products request
			$.ajax({
				url: this.cfg.remote_path + "?request=ministore_list&obj=" + this.opt.obj + "&_step=" + this.opt.step + "&_start=" + this.state.list_start + url_mode_cat,
				dataType: "jsonp",
				context: this,
				success: function(data) {
					// Maintenance
					if (data.status == "maintenance") {
						this.el.html("<p style=\"color: #999999;\">Please try again later</p>");
						return false;
					}
					
					// Finished loading
					this.loading = false;
					
					// Show list title
					var prod_list = "<div class=\"list_title\">" + this.state.list_title + "</div><ul class=\"" + (this.opt.listmode == "photo" ? "list_photo" : "") + "\" style=\"zoom: 1;\">", cnt, i = 0, len = Math.min(data.length, this.opt.step);
					
					var tmp_mode = {summary : 1, full: 1}
					
					// Build products list
					for (;i < len; i ++) {
						prod_list += "<li>" +
								"<a href=\"" + data[i].prod_link + "\" class=\"prod_thumb\" title=\"" + data[i].prod_name + "\"><img src=\"" + data[i].prod_thumb + "\" alt=\"" + data[i].prod_name + "\" /></a>" +
								(tmp_mode[this.opt.listmode] ?
								"<a href=\"" + data[i].prod_link + "\" class=\"prod_name\">" + data[i].prod_name + "</a>" +
								(data[i].prod_price ? "<div class=\"prod_price\">" + data[i].prod_price + "</div>" : "") : "") +
								
								(this.opt.listmode == "full" ? "<span class=\"prod_desc\">" + data[i].prod_desc + "</span>" : "") +
							"</li>";
							
						cnt = i + 1;
						if ( (cnt % this.opt.rowitems == 0) && (cnt < len) && (this.opt.rowitems > 1) ) {
							prod_list += "<li class=\"row_spacer\">&nbsp;</li>";
						}
					}
					prod_list += "</ul>";
					
					// Reset list scroll
					this.list.scrollTop(0).html(prod_list);
					
					// Update state
					this.state.list_prev = this.state.list_start > 0;
					this.state.list_next = data.length > this.opt.step;
					
					// Update navigation
					this._updateNav.call(this);
				}
			});
		};
		
		// Load product view
		this._loadView = function(dir) {
			
			if ( (dir == 1 && !this.state.view_next) || (dir == -1 && !this.state.view_prev) || this.loading) {
				return;
			}
		
			this.loading = true;
		
			if (dir == undefined) {
				// Unchange view start
			}
			else {
				this.view.scrollTop(0).append(SHP.ajax_content_loader);
				
				this.state.view_start = this.state.view_start + dir * 1;
				this.state.view_start = Math.max(0, this.state.view_start);
			}
			
			var url_mode_cat = (this.state.cat == "new" ? "&mode=new" : (this.state.cat == "deals" ? "&mode=deals" : (this.state.cat > 0 ? ("&cat=" + this.state.cat) : "")));
			
			// Product request
			$.ajax({
				url: this.cfg.remote_path + "?request=ministore_view&obj=" + this.opt.obj + "&_start=" + this.state.view_start + url_mode_cat + "&linktagging=" + this.opt.linktagging,
				dataType: "jsonp",
				context: this, 
				success: function(data) {
					// Maintenance
					if (data.status == "maintenance") {
						this.el.html("<p style=\"color: #999999;\">Please try again later</p>");
						return false;
					}
				
					// Finished loading
					this.loading = false;
					var prod_view = "";
					
					// Build product view
					prod_view = "<div class=\"prod_view\"><a href=\"" + data[0].prod_link + "\" target=\"_blank\" class=\"prod_thumb\"><img src=\"" + data[0].prod_thumb + "\" alt=\"" + data[0].prod_name + "\" /><span class=\"zoom png\">&nbsp;</span></a>" +
					"<a href=\"" + data[0].prod_link + "\" target=\"_blank\" class=\"prod_name\">" + data[0].prod_name + "</a>" +
					(data[0].prod_cat_key ? ("<div class=\"prod_cat\"><a href=\"#\" data-key=\"" + data[0].prod_cat_key + "\">" + data[0].prod_cat + "</a></div>") : "") +
					(data[0].prod_price ? "<div class=\"prod_price\">" + data[0].prod_price + "</div>" : "") +
					"<div style=\"margin: 0.5em 0;\"><a href=\"" + data[0].prod_link + "\" target=\"_blank\" class=\"btn_buy\"><span>" + this.cfg.lang_prod_buy + "</span></a></div>" +
					"<span class=\"prod_desc\">" + data[0].prod_desc + "</span>" +
					"<div style=\"margin: 0.5em 0;\">" + data[0].prod_share + "</div>" +
					"</div>";
					
					// Reset view scroll
					this.view.scrollTop(0).html(prod_view);
					
					// Update state
					this.state.view_prev = this.state.view_start > 0;
					this.state.view_next = data.length > 1;
					
					// Update navigation
					this._updateNav.call(this);
				}
			});
		};
		
		// Update navigation 
		this._updateNav = function() {
			// List or view mode
			if ({view: 1, list: 1}[this.state.display_mode]) {
				if (!this.state[this.state.display_mode + "_prev"] && !this.state[this.state.display_mode + "_next"]) {
					this.nav.find(".page_nr").text("");
				}
				else {
					this.nav.find(".page_nr").text("Pg #" + Math.ceil(this.state[this.state.display_mode + "_start"] / (this.state.display_mode == "view" ? 1 : this.opt.step) + 1));
				}
				this.nav.find(".nav_prev")[(!this.state[this.state.display_mode + "_prev"] ? "add" : "remove") + "Class"]("nav_prev_off");
				this.nav.find(".nav_next")[(!this.state[this.state.display_mode + "_next"] ? "add" : "remove") + "Class"]("nav_next_off");
			}
			// Category mode
			else if (this.state.display_mode == "cat") {
				this.nav.find(".page_nr").text("");
				this.nav.find(".nav_prev").addClass("nav_prev_off");
				this.nav.find(".nav_next").addClass("nav_next_off");
			}
			
			// Toggle back button
			if (this.state_arr.length > 0) {
				this.nav.find(".nav_back").show();
			}
			else {
				this.nav.find(".nav_back").hide();
			}
			
			this.nav.find(".page_nr").css({float: "right"});
			if (this.nav.height() > 35) {
				this.nav.find(".page_nr").css({float: "none", display: "block", textAlign: "right"});
			}
			
			var new_height = this.opt.height - this.hd.outerHeight(true) - this.nav.outerHeight(true) - this.ft.outerHeight(true)
			this.cat.height(new_height);
			this.list.height(new_height);
			this.view.height(new_height);
		};
		
		// Init widget
		this.init.call(this, opt);
	};
	
	// Extend from WidgetBase
	SHP.WidgetMinistore.prototype = new SHP.WidgetBase;
};
