﻿$ = jQuery;

Type.registerNamespace("NS.UI");

Date.prototype.addMilliseconds = function(value){
	/// <param name="value" type="Number" integer="true"></param>
	this.setTime(this.getTime() + value);return this;
}
Date.prototype.addSeconds = function(value){
	/// <param name="value" type="Number" integer="true"></param>
	this.addMilliseconds(value*1000);return this;
}
Date.prototype.addMinutes = function(value){
	/// <param name="value" type="Number" integer="true"></param>
	this.addMilliseconds(value*60000);return this;
}
Date.prototype.addHours = function(value){
	/// <param name="value" type="Number" integer="true"></param>
	this.addMilliseconds(value*3600000);return this;
}
Date.prototype.addDays = function(value){
	/// <param name="value" type="Number" integer="true"></param>
	this.setDate(this.getDate()+value);return this;
}
Date.prototype.addMonths = function(value){
	/// <param name="value" type="Number" integer="true"></param>
	this.setMonth(this.getMonth()+value);return this;
}
Date.prototype.addYears = function(value){
	/// <param name="value" type="Number" integer="true"></param>
	this.setFullYear(this.getFullYear()+value);return this;
}

NS.WebRequest=function(){throw "Cannot instantiate static class.";}
NS.WebRequest.invoke = function(path, useGet, params, onSuccess, onFailure, userContext, timeout) {
	/// <param name="path" type="String"></param>
	/// <param name="useGet" type="Boolean"></param>
	/// <param name="params"></param>
	/// <param name="onSuccess" type="Function" mayBeNull="true" optional="true"></param>
	/// <param name="onFailure" type="Function" mayBeNull="true" optional="true"></param>
	/// <param name="userContext" mayBeNull="true" optional="true"></param>
	/// <returns type="Sys.Net.WebRequest"></returns>
	if (!params) params = {};
	var request = new Sys.Net.WebRequest();
	if (!useGet) {
		if(typeof params==="string")
		var body = (typeof params!=="string")? Sys.Serialization.JavaScriptSerializer.serialize(params) : params;
		if (body === "{}") body = "";
		request.set_body(body);
	}
	request.set_url(Sys.Net.WebRequest._createUrl(path, (useGet)?params:{}));

	request.add_completed(onComplete);
	if (timeout && timeout > 0) request.set_timeout(timeout);
	request.invoke();

	function onComplete(response, eventArgs) {
		if (response.get_responseAvailable()) {
			var statusCode = response.get_statusCode();

			var result = null;
			try {
				var contentType = response.getResponseHeader("Content-Type");
				if (contentType.startsWith("application/json"))
					result = response.get_object();
				else if (contentType.startsWith("text/xml"))
					result = response.get_xml();
				else result = response.get_responseData();
			} catch (ex) {}

			//handle errors
			if ((statusCode < 200) || (statusCode >= 300)) {
				if (onFailure) {
					if (!result) {
						result = new Sys.Net.WebServiceError(false , "WebRequest failed for an unknown reason.", "", "");
					}
					result._statusCode = statusCode;
					onFailure(result, userContext);
				}
				else {//dev doesn't want to handle the error, just alert it
					var error;
					if (result)
						error = result.get_exceptionType() + "-- " + result.get_message();
					else error = response.get_responseData();
					window.alert("WebRequest Failed: "+error);
				}
			}
			else if (onSuccess) {
				onSuccess(result, userContext);
			}
		}
		else {
			var msg;
			if (response.get_timedOut()) msg = "WebRequest timed out.";
			else msg = "WebRequest failed for an unknown reason.";

			if (onFailure) onFailure(new Sys.Net.WebServiceError(response.get_timedOut(), msg, "", ""), userContext);
			else alert(msg);
		}
	}
	return request;
}
NS.WebRequest.registerClass('NS.WebRequest');




NS.UI.Tooltip = function (element){
	// Create the div element
	this._tipDiv = document.createElement("div");
	this._tipDiv.innerHTML = '<div class="innerwrapper origin_tl arrow_lt"><div class="closeButton"></div><div class="arrow"></div><div class="corner"></div><div class="top"></div><div class="content"></div></div>';
	this._tipDiv.className = 'tooltip';	
	NS.UI.Tooltip.initializeBase(this,[element]);
}
	
NS.UI.Tooltip.prototype = {
	_tipDiv: null,
	get_classes : function(){return this._tipDiv.firstChild.className;},
	set_classes : function(value){this._tipDiv.firstChild.className = value;},
	get_content : function(){return this._tipDiv.firstChild.lastChild.innerHTML;},
	set_content : function(value){this._tipDiv.firstChild.lastChild.innerHTML = value;},	
	get_tipDiv : function(){return this._tipDiv;},
	set_tipDiv : function(value){this._tipDiv = value;},	
	initialize : function(){		
        // Add the div element to the current objetc
		this._element.appendChild(this._tipDiv); 
		
		// attach a close event to the close button image
		$addHandler(this._tipDiv.firstChild,"click", Function.createDelegate(this,function(){this._tipDiv.style.display='none';}));
	},
	dispose : function(){
	  $clearHandlers(this._element);	  
	  NS.UI.Tooltip.callBaseMethod(this, 'dispose');
	},
    show : function(){
      var bounds = Sys.UI.DomElement.getBounds(this.get_element());
      this._tipDiv.style.top = (bounds.y + bounds.height / 2 -16) + 'px';
      this._tipDiv.style.left = (bounds.x + bounds.width) + 'px';
      this._tipDiv.style.display='block';
      
      var handler = this.get_events().getHandler('visibilityChanged');
        if(handler) {
            var eventArgs = new Sys.EventArgs();
            handler(this, eventArgs);
        }
    },
    hide : function(){
      this._tipDiv.style.display='none';
    },
    add_visibilityChanged : function(handler) {
        this.get_events().addHandler("visibilityChanged", handler);
    },
    remove_visibilityChanged : function(handler) {
        this.get_events().removeHandler("visibilityChanged", handler);
    }
}
NS.UI.Tooltip.registerClass('NS.UI.Tooltip', Sys.UI.Control);

Type.registerNamespace('NS.UI.TooltipBehavior');

NS.UI.TooltipBehavior.Hover = function(element)
{
   NS.UI.TooltipBehavior.Hover.initializeBase(this, [element]);
}

NS.UI.TooltipBehavior.Hover.prototype = {
	_hideDelay: 500,
	_showDelay: 0,
	_timerID: 0,
    
    get_hideDelay : function(){return this._hideDelay;},
	set_hideDelay : function(value){this._hideDelay = value;},
    get_showDelay : function(){return this._showDelay;},
	set_showDelay : function(value){this._showDelay = value;},

    initialize : function(){
        NS.UI.TooltipBehavior.Hover.callBaseMethod(this, 'initialize');
   
        // get a ref to the base element
        var el = this.get_element();
      
        // add a mouse out handler to the tool tip div
        $addHandler(el.lastChild,"mouseout", Function.createDelegate(this,this._delayedHide));
        $addHandler(el,"mouseover", Function.createDelegate(this,this._delayedShow));
        $addHandler(el,"mouseout", Function.createDelegate(this,this._delayedHide));        
   },
   dispose : function(){
        $clearHandlers(this.get_element().lastChild);
        $clearHandlers(this.get_element());
      
        NS.UI.TooltipBehavior.Hover.callBaseMethod(this, 'dispose');
   },
	_clearTimerID: function(){
		if (this._timerID){
			clearTimeout(this._timerID);
			this._timerID = 0;
		}
	},
	_hide: function(args){
		this.get_element().control.hide();
	},
	_delayedShow: function(e){
		this._clearTimerID();		
		this._timerID = window.setTimeout(Function.createDelegate(this,this._show),this._showDelay);
	},	
	_show: function(e){
//	    var b = Sys.UI.DomElement.getBounds(this.get_element());
//	    this.get_element().control._tipDiv.style.margin_left = (b.x + b.width).toString() + 'px';
	    //Sys.UI.DomElement.setLocation(this.get_element().control._tipDiv, b.x + b.width, b.y);
		this.get_element().control.show();
	},
	_delayedHide: function(e){
		this._clearTimerID();		
		this._timerID = window.setTimeout(Function.createDelegate(this,this._hide),this._hideDelay);
	}
}

NS.UI.TooltipBehavior.Hover.registerClass('NS.UI.TooltipBehavior.Hover', Sys.UI.Behavior);

NS.UI.TooltipBehavior.AutoPos = function(element)
{
   NS.UI.TooltipBehavior.AutoPos.initializeBase(this, [element]);
}

NS.UI.TooltipBehavior.AutoPos.prototype = {
    _tipDiv: Function.emptyFunction,
    _quadrants: ["origin_br arrow_rb","origin_bl arrow_lb","origin_tr arrow_rt","origin_tl arrow_lt"],
    
    get_quadrants : function(){return this._quadrants;},
	set_quadrants : function(value){this._quadrants = value;},
    
    initialize : function(){
        NS.UI.TooltipBehavior.AutoPos.callBaseMethod(this, 'initialize');
   
        // get a ref to the base element
        var el = this.get_element();
                      
        // get the width and height of the tipDiv for positioning
        this._setTipDivWH(el.lastChild);                
        
        el.control.add_visibilityChanged(Function.createDelegate(this,this._setPos));                
   },
   dispose : function(){
      NS.UI.TooltipBehavior.AutoPos.callBaseMethod(this, 'dispose');
   },
   _setTipDivWH : function(tipDiv){
        var style = tipDiv.style;
        
        style.visibility = 'hidden';
        style.display = 'block';        
        
        this._tipDiv.height = tipDiv.firstChild.clientHeight;
        this._tipDiv.width = tipDiv.firstChild.clientWidth;        
        
        style.display = 'none';
        style.visibility = 'visible';
   },
   _setPos : function(e){
    
        var el = this.get_element();
        var tipDiv = el.lastChild;
        
        el.Hover._clearTimerID();
        
        var minX = (typeof(window.pageXOffset) !== 'undefined') ? window.pageXOffset : document.documentElement.scrollLeft;
        var minY = (typeof(window.pageYOffset) !== 'undefined') ? window.pageYOffset : document.documentElement.scrollTop;
        var maxX = (window.innerWidth ? window.innerWidth : document.documentElement.clientWidth);
        var maxY = (window.innerHeight ? window.innerHeight : document.documentElement.clientHeight);
        
        var quadrant = 3;
                
        // determine the quadrant that the tooltip should appear in
        quadrant = (el.offsetLeft - this._tipDiv.width > minX ? 
                    (el.offsetTop - minY + this._tipDiv.height > maxY && el.offsetTop - (this._tipDiv.height) > minY ? 1 : 3) :
                      (el.offsetTop - minY + this._tipDiv.height > maxY ? 2 : 4));
                
        var posCss = this._quadrants[quadrant-1];
                
        tipDiv.firstChild.className = 'innerwrapper ' + posCss;
        tipDiv.style.display = 'block';   
   }   
}

NS.UI.TooltipBehavior.AutoPos.registerClass('NS.UI.TooltipBehavior.AutoPos', Sys.UI.Behavior);

NS.UI.getElementsByClassName = function(className, element) {
    element = element || document;
    className = ' ' + className + ' ';
    var potentials = element.all || element.getElementsByTagName("*");
    var l = potentials.length, results = [], i;
    for (i = 0; i < l; i++) {
        if ((' ' + potentials[i].className + ' ').indexOf(className) !== -1) {
            results[results.length] = potentials[i];
        }
    }
    return results;
};

$q = YAHOO.util.Selector.query;

