﻿// Widget script

(function($) {
	function applyFormResponse(refEl, html, status) {	   
		if(status == 'success') {
		       if(html.indexOf("<widgetRedirect") === 0) {        
		            window.location = html.substring(html.indexOf('=')+1,html.length-2);
		       }
		       else {
		            var formparent=$(refEl.parentNode);
		            html = html.replace(/javascript:__doPostBack\(/g, 'javascript:__widgetPostBack(' + '\'' + $(refEl).attr('id') + '\',');
		            if(formparent.attr('class') == 'widgetWrapper') { 
                        formparent.empty().append(html);
                    }
               }
		}
	}
	
	function prependImage(prependElement) {
	    var imageTag = 'Loading..';
	    if(typeof(hostConfig) != 'undefined') {
	        imageTag = "<img alt='Loading..' src='" + hostConfig.LoadingImagePath +"' />";
	    }
	    prependElement.prepend("<div class='overlayImage'><center>"+imageTag+"</center></div>"); 
	}
	
	function loadWidget(refEl, href) {
	    var $refEl = $(refEl);	
	    prependImage($refEl);
	    showLoadingImage($refEl.children('.overlayImage'),refEl,true);
		$.get(href, function(html, status) {		    
			applyFormResponse(refEl, html, status);
		});
	}  
	
	
	function showLoadingImage($refEl,form,isInitial){
	    var $form = $(form);
	    if(isInitial || $form.widget().isLoadingImageEnabled()) {	        	  
		    $refEl.height($form.height());
	        $refEl.width($form.width());	     
	        $refEl.show();
	    }
	}

	
	function displayError(refEl,$loadingImage,requestObject){
	        var $title = $(refEl).find('.title');
	        if($title.length == 1) { 
	            var title = $title.html();
	            if(title.indexOf("Error") < 0) {	   
	                $title.append("Error");
	            }
	        }
	    $loadingImage.hide();
	}
	
	$.extend($.fn, {
		widget : function() {
			var widgets = [];
			this.each(function (){
				var form = null;
				var $this = $(this);
				if($this.is('.widgetForm')) {
					form = this;
				}
				else {
					var $form = $this.parents('.widgetForm');
					if($form.length == 1){
						form = $form.get(0);
					}
				}
				if(form) {
					var instance = $.data(form, 'widget') || $.data(form, 'widget', new $.widget(form));
					widgets.push(instance);
				}
			});
			if(widgets.length == 1) {
				return widgets[0];
			}
			else {
				return new $.widgetCollection(widgets);
			}
		},
		
		widgetTimer : function() {
		    var timers = [];
		    this.each(function() {
		        timers.push($.widgetTimer.getOrCreate(this));
		    });
		    return timers[0];
		}
	});
	
    $.delegate = function(obj, method, args) {
        return function() {
            return method.apply(obj, args ? args : []);
        };
    };

	$.styleSheetManager = new (function(){
		var stylesInDom = [];
		
		var head = document.getElementsByTagName('head')[0];
		
		var isStyleSheetInDom = function(href) {
			var available = false;
			if(typeof(href) == 'string') {
				href = href.toLowerCase();
				for(var i = 0; i < stylesInDom.length; ++i) {
					if(stylesInDom[i].indexOf(href) >= 0) {
						available = true;
						break;
					}
				}
			}
			return available;
		};
		
		var markToBeInDom = function(href) {
			if(typeof(href) == 'string') {
				href = href.toLowerCase();
				stylesInDom.push(href);
			}
		};
		
		var addToDom = function(href) {
			if(isStyleSheetInDom(href) == false) {
				var link = document.createElement('link');
				var attributes = {
					href : href,
					rel : 'stylesheet',
					type : 'text/css'
				};
				
				var $link = $(link);
				for(var name in attributes) {
					$link.attr(name, attributes[name]);
				}
			
				markToBeInDom(href);
				window.setTimeout(function() {
					head.appendChild(link);
				}, 0);
			}
		};
		
		$(function() {
			$('link', head).each(function() {
				markToBeInDom($(this).attr('href'));
			});
		});
		
		this.addStyle = function(href) {
			if(typeof(href) == 'string') {
				addToDom(href);
			}
			return this;
		};
	})();
    
	$.widgetTimer = function(timerEl) {
	    this.timerEl = timerEl;
	    this.$timerEl = $(timerEl);
	};
	
	$.widgetTimer.getOrCreate = function(timerEl) {
	    var instance = timerEl.timer;
	    if(!instance) {
	        instance = new $.widgetTimer(timerEl);
	        timerEl.timer = instance;
	    }
	    return instance;
	};
	
	$.widgetTimer.destruct = function(timerEl) {
	    if(timerEl.timer) {
            try {
				delete timerEl['timer'];
			} catch(e){
				if ( timerEl.removeAttribute ) {
					timerEl.removeAttribute('timer');
				}
			}	    
		}
	}
	
	$.widgetTimer.prototype = {
	    timerEl : null,
	    $timerEl : null,
	    timer : null,
	    interval : null,
	    
	    init : function() {
	        this.interval = parseInt(this.$timerEl.attr('interval'));
	        var disabled = this.$timerEl.attr('disabled');
	        if(!disabled) {
	            this.reset();
	        }
	    },
	    
	    reset : function() {
	        this.stop();
	        this.timer = setInterval($.delegate(this, this.callback), this.interval);
	    },
	    
	    stop : function() {
	        if(this.timer) {
	            clearInterval(this.timer);	            
	            this.timer = null;
	        }
	    },
	       
	 	startTimer: function() {
	        this.$timerEl.attr('disabled','false');
	        this.reset();
	    },
	    
	    stopTimer: function() {
	        this.$timerEl.attr('disabled','true');
	        this.stop();
	    },  
	    
	    
	    callback : function() {
	        var parts = this.$timerEl.attr('href').split("'");
			__widgetPostBack(parts[1], parts[3], parts[5]);
	    },
	    
	    uninit : function() {
	        this.stop();
	        $.widgetTimer.destruct(this.timerEl);
	    }
	};
	
	$.widgetCollection = function(widgets){
		//alert('not done yet');
	};
	
	$.widget = function(form) {
		this.form = form;
		this.$form = $(this.form);
	};
	
	$.widget.prototype = {
		form : null,
		$form : null,
		inited : false,
		propBag : {},
		responsePending : false,
		
		init : function() {
			var form = this.form;
			var $form = this.$form;
			var widget = this;
			prependImage($form);
			
			this.deserializeState();
			

		    var $loadingImageName = $form.children('.overlayImage');	
			var options = {
				semantic : true,
		        beforeSubmit: function(formdata,form,options) {		            
		            if(widget.isResponsePending()) {		              
		                return false;    
		            }
		            widget.setResponsePending(true);		         
		            showLoadingImage($loadingImageName,form,false);
		            return true;			                 
		        },
		        
		        submitNameProvider : function(name) {
					return name.replace('__w', '__');
		        },
		       
		        success: function(html, status){    
		           widget.setResponsePending(false);		            			    		    	   
		           applyFormResponse(form, html, status);
		        },
		        
	            error: function(requestObject, textStatus, errorThrown){ 	               
	               widget.setResponsePending(false);
	               displayError(form,$loadingImageName,requestObject);		        	
	            }
			};
			
		    $form.bind('form-pre-serialize', function () {
		        widget.serializeState();
		    });
		    
			this.doPostBack = function(target, arg) {	
				if(target != undefined) {
					$('#__wEVENTTARGET', form).attr('value', target);
					$('#__wEVENTARGUMENT', form).attr('value', arg);	
				}
				$form.ajaxSubmit(options);
			},
			
		
			this.inited = true;
			$form.trigger('widget-init', [$form]);
		},
		
		ready : function(callback) {
			if(this.inited) {
				callback(this.$form);
			}
			else {
				this.$form.bind('widget-init', callback);
			}
		},
		
		deserializeState : function() {		  
			var propBag = this.propBag;
			var widgetState = this.$form.children('.widgetState').attr('value');

			$.each(widgetState.split(','),function(i,state) {
				var param = state.split('=');
				propBag[param[0]] = param[1];
			});
			propBag.enableWidgetLoadingImage = (propBag.enableWidgetLoadingImage.toLowerCase() == 'true');
		},
		
		serializeState : function () {
			var propBag = this.propBag;
			var stateList = [];
			for(var prop in propBag) {
				stateList.push(prop + '=' + propBag[prop]);
			}
			var $stateTag = this.$form.children('.widgetState');
			$stateTag.attr('value',stateList.join(','));
		},
		
		isLoadingImageEnabled : function() {
			return this.propBag.enableWidgetLoadingImage;	
		},
		
		enableLoadingImage : function(state) {
		   this.propBag.enableWidgetLoadingImage = state;		   
		},
		
		isResponsePending : function() {
			return this.responsePending;	
		},
		
		setResponsePending : function(state) {
		    this.responsePending = state;
		},
		
		uninit : function() {
			this.$form.trigger('widget-uninit', [this.$form]);
			this.form = null;
			this.$form = null;
		}
		
		
	};
	
	$.widgetHost = new (function(){
		this.init = function() {
			var $form = $('form');
			var form = $form.get(0);
			
			$(":submit", form).livequery('click', function(e) {
				//assign to form.clk, this will be used by form submit plugin
				form.clk = this;
				
				//auto clear after timeout
				setTimeout(function() { $form.clk = null; }, 10);
			});
			
			$form.bind('submit.form-plugin', $.delegate(this, function() {
				var widgetForm = $(form.clk).parents('.widgetForm').get(0);
				if(widgetForm != undefined) {
					$(widgetForm).widget().doPostBack();
					return false;
				}
				return true;
			}));
		}
	})();
    
    window.__widgetPostBack = function(formId, target, arg) {
		$('#' + formId).widget().doPostBack(target, arg);
	}	
	
	$($.delegate($.widgetHost, $.widgetHost.init));
	
	// initialize the widget forms and loader hints, this will run as soon as the document is ready
	$(function() {

		$('.widgetForm').livequery(function(){
			$(this).widget().init();
		}, function() {
			$(this).widget().uninit();
		});
		
		$('.widgetForm .timer')
		    .livequery(function() {
			    $(this).widgetTimer().init();
		    }, function() {
		        $(this).widgetTimer().uninit();
		    });
		
		$('.widgetLoaderHint').each(function() {
			loadWidget(this, $(this).attr('src'));
		});				
		
		
	});
})(jQuery);





