/*
=============================================================
						 COPY RIGHTS			
			-------------------------------------
			Przedsiebiorstwo Informatyczne WTSOFT
			-------------------------------------
=============================================================
*/

/**
 * ---------
 * PARAMETRY 
 * ---------
 * jqSelector			- selektor jquery do ktorego ma zaladowac zwrocone dane z adresu - dla "refresh" wymagane
 * jqLoaderSelector		- selektor jquery odpowiadajacy za loader
 * cache				- pamiec true - raz wczytane dane zapamieta, false - wczytuje za kazdym razem
 * prmSep				- separator dla wartosci elementow z atrubutem "submitval" domyslnie "/"
 * callback				- globalna akcja zwrotna
 * navigation			- tablica elementow do nawigacji i wykonania akcji
 * 
 * -----------------
 * TABLICA NAVIGACJI
 * -----------------
 * [jq_selektor_elementu_do_akcji] = {
 * 		type 	: 'refresh / background' 									- gdy puste domyslnie "refresh"
 * 		action 	: 'click / dbclick / keyup / keydown / submit / change' 	- gdy puste domyslnie "click"
 * 		callback: 'funkcja_zwrotna'											- funkcja wykonana po zakonczeniu akcji
 * 		live	: true / false 												- jezeli zdazenie ma byc wykonane za pomoca live - domyslnie false
 * 		opt 	: {
 * 			refreshOnce : true / false			- odswiez tylko raz - domysnie "false"
 * 			noEmpty 	: true / false 			- dla "keyup / keydown" - nie odswiezaj gdy wartosc pola jest pusta - domysnie "false",
 * 			addVal		: 'jq_selektory / true'	- dodaj wartosci tych selektorow do adresu oddzielajac je wartoscia "prmSep" lub wartosc danego pola dla wartosic "true"
 * 		}
 * }
 * 
 * ---------
 * ZDARZENIA
 * ---------
 * click 		- dla linkow <a> w atrybucie href mozemy podac adres do odswierzenia w pozostalych elementach w tablicy navigation [href],
 * dblclick 	- dla linkow <a> w atrbucie href mozemy podac adres do odswierznia w pozostalych elementach w tablicy navigation [href],
 * keyup		- dla input, textare
 * keydown		- dla input, textare
 * submit		- dla formularzy
 * 
 */

(function($){
	$.extend({
		wtsoftAJAX : function(settings){
			var settings = jQuery.extend({
				// Ustawienie cache zapytan
				cache: true,
				cacheElements: {},
				// Elementy dla ktorych zostanie wykonane zapytanie
				jqSelector: null,
				jqLoaderSelector: null,
				loaderOpacity : '0.6',
				// Separator dla parametrow dodatkowych
				prmSep : '/',
				// Elementy dla ktorych ma byc wykonane zdazenia ajax'a
				navigation: null,
				// Funkcja przed wyslaniem zapytania
				beforeSend: null,
				// Funkjca do wykonania po wykonaniu zapytania
				callback: null,
				// Dodatkowe parametry
				queryData: {}
			},settings);
			
			return new $.wtsAJAX(settings);
		},
		wtsAJAX : function(settings){
			var genSets = settings;
			this.genSets = genSets;
			// Ustawienie nawigacji
			this.setNavigation();
		}
	});
	
	$.extend($.wtsAJAX.prototype, {
		
		//----------------------------------
		// -- Zmiena dla obiektu $.ajax() --
		//----------------------------------
		ax : null,
		
		//-----------------------
		// -- Status zapytania --
		//-----------------------
		// 0 - brak wykonania zapytania
		// 1 - w tkracie zapytania
		// 2 - zakonczone sukcesem
		// 3 - zakonczone porazka
		// 4 - nieznany blad
		//-----------------------
		stat : 0,
		
		// Options cache
		optCache : null,
		// Tablica nawigacji
		nav : {},
		// Unikalny id
		uniqId : 0,
		idPref : 'wts-ax-',
		uniqPref : null,
		
		//-------------------
		// -- Ustaw status --
		//-------------------
		setStatus : function(stat){
			if(typeof(stat) != 'number' || (stat < 0 && stat > 4))
				this.stat = 5;
			else this.stat = stat;
			return true;
		},
		
		//---------------------
		// -- Pobierz status --
		//---------------------
		getStatus : function(){
			return this.stat;
		},
		
		//----------------------------------
		// -- Pobierz / ustaw id elementu --
		//----------------------------------
		elementId : function(obj){
			if(typeof(obj) != 'object' || obj.length == 0) return false;
			// Przepisz obiekt
			var self = this;
			// Ustaw unikalny prefiks
			if(self.uniqPref == null) self.uniqPref = Math.floor(Math.random() * 100000);
			var objId = obj.attr('id');
			if(!objId){
				objId = self.idPref+self.uniqPref+'-'+(self.uniqId++);
				obj.attr('id',objId);
			}
			return objId;
		},
		
		//--------------------
		// -- Wykonaj akcje --
		//--------------------
		action : function(obj){
			if(typeof(obj) != 'object' || obj.length == 0) return false;
			// Przepisanie obiektu
			var self = this;
			// Pobierz id obiektu
			var objId = self.elementId(obj);
			// Pobierz opcje
			var opt = self.nav[objId];
			if(!opt || typeof(opt) != 'object') return false;
			
			//------------------------
			// Pojedyncze odswierzenie
			//------------------------
			// Sprawdz czy jest wlaczone
			if(opt['opt'] && opt['opt']['refreshOnce'] && opt['opt']['refreshOnce'] == true){
				// Przerwij akcje jezeli odswierzony
				if(self.optCache != null && self.optCache[opt['id']]['refreshOnce'] && self.optCache[opt['id']]['refreshOnce'] == 1) return true;
				// Zapamietaj odswierzenie
				if(self.optCache == null) self.optCache = {};
				if(!self.optCache[opt['id']]) self.optCache[opt['id']] = {};
				self.optCache[opt['id']]['refreshOnce'] = 1;
			}
			
			//--------------------------
			// Link / adres do wykonania
			//--------------------------
			var makeHref = '';
			if(opt['href']) makeHref = opt['href'];
			else{
				if(opt['action'] == 'submit')
					var objHref = obj.attr('action');
				else
					var objHref = obj.attr('href');
				if(!objHref) return false;
				makeHref = objHref;
			}
			
			//---------------------------------------
			// Dodatkowe parametry / opcje dla adresu
			//---------------------------------------
			// Dodaj wartosci selektorow
			if(opt.opt && opt['opt']['addVal']){
				if(opt['opt']['addVal'] === true){
					// Wartosc aktualnego pola dla "keyup / keydown"
					var objVal = obj.val();
					// Jezeli opcja "noEmpty" jest wlaczona przerwij akcje
					if(opt['opt'] && opt['opt']['noEmpty'] && opt['opt']['noEmpty'] == true && objVal == ''){
						self.abort();
						return false;
					}
					makeHref += objVal + self.genSets.prmSep;
				}else{
					if($(opt['opt']['addVal']).length > 0){
						$(opt['opt']['addVal']).each(function(){
							// Pobierz wartosc 
							var elVal = $(this).val();
							// Dodaj wartosc do adresu lub "0" gdy pusta wartosc
							if(elVal) makeHref += elVal + self.genSets.prmSep;
							else makeHref += '0' + self.genSets.prmSep;
						});
					}
				}
			}
			
			//-------------------------------------
			// Dla formularzy przekaz parametry pol
			//-------------------------------------
			if(opt['action'] == 'submit'){
				var formParams = {};
				// Zapisz pola
				$(':input:not(:submit)',obj).each(function(){
					formParams[$(this).attr('name')] = $(this).val();
				});
				// Zapisz przycisk ktory wykonal zapytanie
				if(opt['submit'] && opt['submit'].length)
					formParams[opt['submit'].attr('name')] = opt['submit'].val();
				
				if(opt['clearQueryData'])
					opt['queryData'] = formParams;
				else opt['queryData'] = jQuery.extend(opt['queryData'],formParams);
			}
			
			//----------------
			// Funkcja zwrotna
			//----------------
			var callback = opt['callback'];
			if(!callback) callback = self.genSets.callback;
			
			//-----------------------------
			// Wykonaj odpowiedni typ akcji
			//-----------------------------
			switch(opt['type']){
				// REFRESH BACKGROUND
				case 'background':
					self.makeBackground({
						href: makeHref,
						dataType: 'json',
						clearQueryData : opt['clearQueryData'],
						queryData: opt['queryData'],
						contentType : opt.contentType? opt.contentType : 'application/x-www-form-urlencoded'
					},callback);
					break;
				
				// REFRESH
				case 'refresh':
				default:
					self.make({
						href: makeHref,
						queryData: opt['queryData'],
						clearQueryData : opt['clearQueryData'],
						contentType : opt.contentType? opt.contentType : 'application/x-www-form-urlencoded'
					},callback);
				break;
			}
			return false;
		},
		
		//---------------------------------------------
		// -- Ustaw opcje dla elementow do nawigacji --
		//---------------------------------------------
		setNavigationOptions : function(){
			// Przepisanie obiektu
			var self = this;
			// Sprawdz czy jest zapisana jakas nawigacja
			if(self.genSets.navigation == null || typeof(self.genSets.navigation) != 'object') return false;
			
			// Ustaw nawigacje
			for(var i in self.genSets.navigation){
				// Pobierz obiekt/y
				var obj = $(i);
				// Jezeli obiekt nie istnieje przejdz do kolejnego
				if(obj.length == 0) continue;
				// Pobierz opcje dla nawigacji
				var opt = self.genSets.navigation[i];
				// Ustaw dla kazdego pasujacego elementu
				obj.each(function(){
					// Pobierz / ustaw unikalny id dla obiektu
					var objId = self.elementId($(this));
					// Zapisz opcje do pamieci
					self.nav[objId] = opt;
				});
			}
			
			return true;
		},
		
		//----------------------
		// -- Ustaw nawigacje --
		//----------------------
		setNavigation : function(){
			// Przepisanie obiektu
			var self = this;
			// Sprawdz czy jest zapisana jakas nawigacja
			if(self.genSets.navigation == null || typeof(self.genSets.navigation) != 'object') return false;
			
			// Ustaw opcje dla elementow nawigacyjnych
			self.setNavigationOptions();
			
			// Ustaw nawigacje
			for(var i in self.genSets.navigation){
				// Pobierz obiekt/y
				var obj = $(i);
				
				// Pobierz opcje dla nawigacji
				var opt = self.genSets.navigation[i];
				
				// Ustaw return
				var ret = (opt['ret']? opt['ret'] : false);
				switch(opt['action']){
				case 'dbclick':
					if(opt['live']){
						obj.live('dbclick',function(){
							self.action($(this));
							return ret;
						});
					}else{
						obj.dbclick(function(){
							self.action($(this));
							return ret;
						});
					}
					break;
				case 'keyup':
					if(opt['live']){
						obj.live('keyup',function(){
							self.action($(this));
							return ret;
						});
					}else{
						obj.keyup(function(){
							self.action($(this));
							return ret;
						});
					}
					break;
				case 'keydown':
					if(opt['live']){
						obj.live('keydown',function(){
							self.action($(this));
							return ret;
						});
					}else{
						obj.keydown(function(){
							self.action($(this));
							return ret;
						});
					}
					break;
				case 'change':
					if(opt['live']){
						obj.live('change',function(){
							self.action($(this));
							return ret;
						});
					}else{
						obj.change(function(){
							self.action($(this));
							return ret;
						});
					}
					break;
				case 'submit':
					if(opt['live']){
						$(':submit',obj).live('click',function(){
							var form = $(this).parents('form');
							var formId = self.elementId(form);
							self.nav[formId]['submit'] = $(this);
						});
						obj.live('submit',function(){
							self.action($(this));
							return ret;
						});
					}else{
						$(':submit',obj).click(function(){
							var form = $(this).parents('form');
							var formId = self.elementId(form);
							self.nav[formId]['submit'] = $(this);
						});
						obj.submit(function(){
							self.action($(this));
							return ret;
						});
					}
					break;
				case 'click':
				default:
					if(opt['live']){
						obj.live('click',function(){
							if(typeof(wts_confirm_result) != 'undefined' && wts_confirm_result === false){
								wts_confirm_result = undefined;
								return ret;
							}else{
								self.action($(this));
								return ret;
							}
						});
					}else{
						obj.click(function(){
							if(typeof(wts_confirm_result) != 'undefined' && wts_confirm_result === false){
								wts_confirm_result = undefined;
								return ret;
							}else{
								self.action($(this));
								return ret;
							}
						});
					}
					break;
				}
				
			}
		},
		
		// -----------------------------
		// -- Wykonaj zapytanie w tle --
		// -----------------------------
		makeBackground: function(settings, callback){
			var sets = jQuery.extend({
				// Typ zapytania
				method: 'post',
				// Adres strony do wykonania
				href: null,
				// Dodatkowe opcje do zapytania
				queryData: {},
				// Nie uzywaj danych globlanych
				clearQueryData : false,
				dataType: 'json',
				loaderObj: null,
				// Opcja wylancza przerywananie zapytania
				noCut: false
			},settings);
			
			// Przepisanie obiektu
			var self = this;
			
			// Ustaw dodatkowe parametry
			if(!sets.clearQueryData)
				sets.queryData = jQuery.extend(self.genSets.queryData,sets.queryData)
			
			// Zatrzymywanie poprzedniego zapytania
			if(sets.noCut == false)
				self.cut();
			
			// Sprawdz poprawnosc url
			if(!sets.href || sets.href.length == 0 || typeof(sets.href) != 'string' || sets.href == '#')
				return false;
				
			// Pokazywanie loadera
			if(sets.loaderObj)
				self.showLoader(sets.loaderObj);
			else if(self.genSets.jqLoaderSelector)
				self.showLoader($(self.genSets.jqLoaderSelector));
			// Wykonanie zapytania
			self.ax = $.ajax({
				type: sets.method,
				url: sets.href,
				dataType: sets.dataType,
				data: sets.queryData,
				contentType : sets.contentType,
				beforeSend : function(){
					// Ustaw status - w trakcie wykonywania
					self.setStatus(1);
					if(typeof self.genSets.beforeSend == 'function'){
						self.genSets.beforeSend();
					}
				},
				success: function(data){
					// Funkcja uzytkownika
					if(typeof(callback) == 'string') {
						self.make({
							href: callback,
							jqSelector: self.genSets.jqSelector,
							jqLoaderSelector: self.genSets.jqLoaderSelector,
							queryData: (typeof data == 'object' ? data : {})
						});
					}else if(typeof(callback) == 'function'){
						callback(data);
						// Chowanie loadera
						if(sets.loaderObj)
							self.hideLoader(sets.loaderObj);
						else if(self.genSets.jqLoaderSelector)
							self.hideLoader($(self.genSets.jqLoaderSelector));
					}else{
						// Chowanie loadera
						if(sets.loaderObj)
							self.hideLoader(sets.loaderObj);
						else if(self.genSets.jqLoaderSelector)
							self.hideLoader($(self.genSets.jqLoaderSelector));
					}
					// Ustaw status - wykonane powodzeniem
					self.setStatus(3);
					// Ustaw opcje elementow nawigacji
					self.setNavigationOptions();
				},
				error: function(){
					// Chowanie loadera
					if(sets.loaderObj)
						self.hideLoader(sets.loaderObj);
					else if(self.genSets.jqLoaderSelector)
						self.hideLoader($(self.genSets.jqLoaderSelector));
					// Ustaw status - zakonczone porazka
					self.setStatus(4);
				}
			});
			
			return true;
		},
		
		// -----------------------
		// -- Wykonaj zapytanie --
		// -----------------------
		make : function(settings, callback){
			var sets = jQuery.extend({
				// Typ zapytania
				method: 'post',
				// Adres strony do wykonania
				href: null,
				// Dodatkowe opcje do zapytania
				queryData: {},
				// Nie uzywaj danych globlanych
				clearQueryData : false,
				dataType: 'html'
			},settings);
			
			// Przepisanie obiektu
			var self = this;
			
			// Ustaw dodatkowe parametry jezeli nie wylaczone
			if(!sets.clearQueryData)
				sets.queryData = jQuery.extend(self.genSets.queryData,sets.queryData)
			// Zatrzymywanie poprzedniego zapytania
			self.cut();
			
			var jqMatchedObj = $(self.genSets.jqSelector);
			if(jqMatchedObj.length == 0)
				return false;
			// Sprawdz poprawnosc url
			if(!sets.href || sets.href.length == 0 || typeof(sets.href) != 'string' || sets.href == '#') return false;
			
			// Sprawdzanie cache
			var cache = false;
			if(self.genSets.cache == true){
				for(i in self.genSets.cacheElements){
					var element = self.genSets.cacheElements[i];
					if(element.href == sets.href){
						cache = true;
						var data = element.data;
					}
				}
			}
			// Wczytywanie danych z cache
			if(cache == true){
				jqMatchedObj.html(data);
				// Funkcja uzytkownika
				if(typeof callback == 'function'){
					callback();
				}
				// Chowanie loadera
				if(self.genSets.jqLoaderSelector)
					self.hideLoader($(self.genSets.jqLoaderSelector));
			}else{
				// Pokazywanie loadera
				if(self.genSets.jqLoaderSelector)
					self.showLoader($(self.genSets.jqLoaderSelector));
				// Wykonanie zapytania
				self.ax = $.ajax({
						type: 		sets.method,
						url: 		sets.href,
						dataType: 	sets.dataType,
						data: 		sets.queryData,
						beforeSend : function(){
						// Ustaw status - w trakcie wykonywania
						self.setStatus(1);
						if(typeof self.genSets.beforeSend == 'function'){
							self.genSets.beforeSend();
						}
					},
					success: function(data){
						jqMatchedObj.html(data);
						// Cache'owanie wynikow zapytan
						if(self.genSets.cache == true){
							self.genSets.cacheElements[sets.href] = {};
							self.genSets.cacheElements[sets.href].href = sets.href;
							self.genSets.cacheElements[sets.href].data = data;
						}
						// Funkcja uzytkownika
						if(typeof callback == 'function'){
							callback();
						}
						// Chowanie loadera
						if(self.genSets.jqLoaderSelector)
							self.hideLoader($(self.genSets.jqLoaderSelector));
						// Ustaw status - wykonane powodzeniem
						self.setStatus(3);
						// Ustaw opcje elementow nawigacji
						self.setNavigationOptions();
					},
					error: function(xhr, textStatus, error){
						// Chowanie loadera
						if(sets.loaderObj)
							self.hideLoader(sets.loaderObj);
						else if(self.genSets.jqLoaderSelector)
							self.hideLoader($(self.genSets.jqLoaderSelector));
						// Ustaw status - zakonczone porazka
						self.setStatus(4);
						// Zwroc blad
						alert(textStatus);
					},
					complete : function(xhr, textStatus){
					}
				});
			}
			return false;
		},
		
		// Funkcja dopasowuje rozmiar warstwy loader
		fitLoader: function(obj){
			if(typeof(obj) == 'string')
				obj = $(this.genSets.jqLoaderSelector);
			
			// Pobierz rodzica i jego parametry
			var parent = obj.parent();
			if(parent){
				var wth = parent.outerWidth();
				var hgh = parent.outerHeight();
				// Ustaw parametry rodzica dla loadera
				obj.css({
					width: wth,
					height: hgh,
					opacity: '0.4'
				});
			}
		},
		
		// Funkcja pokazuje loader
		showLoader: function(obj){
			if(!obj && typeof(obj) != 'object' && typeof(obj) != 'string') return false;
			// Dopasuj rozmiar loadera
//			this.fitLoader(obj);
			obj.css({
				opacity: ''
			});
			// Pokaz loader
//			if(obj) obj.stop().fadeTo(300,this.genSets.loaderOpacity);
			if(obj) obj.stop().fadeIn(300);
		},
		
		// Funkcja chowa loader
		hideLoader: function(obj){
			if(!obj && typeof(obj) != 'object' && typeof(obj) != 'string') return false;
			if(typeof(obj) == 'string')
				obj = $(this.genSets.jqLoaderSelector);
			
			// Schowaj loader
			if(obj) obj.stop().fadeOut(300,function(){
				$(this).css('display','none');
			});
		},
		
		cut: function(){
			// Zatrzymuje zapytanie przed rozpoczeciem nastepnego
			if(this.ax && typeof this.ax.abort == 'function'){
				this.ax.abort();
			}
			// Ustaw status - brak zapytania
			this.setStatus(0);
		},
		
		abort : function(){
			// Zatrzymywanie poprzedniego zapytania
			this.cut();
			if(this.genSets.jqLoaderSelector)
				this.hideLoader($(this.genSets.jqLoaderSelector));
		}
	});
})(jQuery)
