﻿/*
	Extensión de la clase Object y otras utilidades
	
	-- Extender
	Extend
	
	-- Estáticas
	Ej.: Ds.IsString(s) -> true/false
	IsFunction	IsString	IsNumber	IsUndefined		IsNullOrUndefined
	
	-- Función $(e)
	Ej.: $("IdElement") -> DOM Element(s) (Object)

	-- Eventos
	Ej.: this.onclick.Bind(this)
	Bind
	
	-- String
	Strip
*/

// ------------------------------------
// --- NameSpace Ds : Root
var Ds = 
{
	// -- Browsers
	
	// -- Extender clases
	Extend : function(dest, source)
	{
		for (var prop in source)
			dest[prop] = source[prop];

		return dest;
	},
	
	// -- Tipos
	IsFunction:        function(o) { return typeof o == "function";  },
	IsString:          function(o) { return typeof o == "string";    },
	IsNumber:          function(o) { return typeof o == "number";    },
	IsUndefined:       function(o) { return typeof o == "undefined"; },
	IsNullOrUndefined: function(o) { return typeof o == "undefined" || o == null; },
	// -- Ajax
	Ajax: function(Opts)
	{
		var o = {};
		Ds.Extend(o,Ds.Ajax.Methods);
		o.Create(Opts);
		
		return o;
	},
	// -- Eventos
	Event: function(evt)
	{
		var e = evt;
		
		if( Ds.IsNullOrUndefined(e))
			e = window.event;
			
		// -- Extender DomElement
		if(Ds.IsNullOrUndefined(e.__dummy))
			Ds.Extend(e, Ds.Event.Methods);
		
		return e;
	},
	AddEvent: function(o, EvName, Fn, UseCapture)
	{
		if (o.addEventListener)
		{
			o.addEventListener(EvName, Fn, UseCapture);
			return o;
		}
		else if (o.attachEvent)
		{
			var pObj = o.attachEvent("on" + EvName, Fn);
			return pObj;
		}
	},
	RemoveEvent: function (o, EvName, Fn, UseCapture)
	{
		if (o.removeEventListener)
		{
			o.removeEventListener(EvName, Fn, UseCapture);
			return o;
		}
		else if (o.detachEvent)
		{
			var pObj = o.detachEvent("on" + EvName, Fn);
			return pObj;
		}
	},
	// -- Acceso rápido - Selectores
	$: function (e)
	{
		if (arguments.length > 1)
		{
			for (var i = 0, elements = [], length = arguments.length; i < length; i++)
				elements.push($(arguments[i]));
			return elements;
		}

		// -- Html strings
		if (Ds.IsString(e))
			e = document.getElementById(e);
		
		if(Ds.IsNullOrUndefined(e))
			return null;

		// -- Extender DomElement
		if(e.nodeType && !e.__dummy)
			Ds.Extend(e, Ds.DomElement);
		
		return e;
	},
	
	// -- Final
	__dummy: 0
}

// ------------------------------------
// --- NameSpace DomElement - Dom Elements
Ds.DomElement = 
{
	// -- Focus 
	Focus: function()
	{
		this.focus();
		return this;
	},
	GetValue: function()
	{
		var sTag = this.tagName.toUpperCase();
		var xVal = "";
			
		if ( sTag == "SELECT" )
			xVal = this.options[this.selectedIndex].value;
		else
		{
			 xVal = this.value;
			
			if( this.type.toUpperCase() == "CHECKBOX" )
				xVal = this.checked;
		}
		
		return xVal;
	},
	SetValue: function(val)
	{
		var sTag = this.tagName.toUpperCase();
			
		if ( sTag == "SELECT" )
		{
			for ( var n = 0; n < this.options.length; n++ )
			{
				if ( this.options[n].value == val )
				{
					this.options[n].selected = true;
					break;
				}
			}
		}
		else
		{
			this.value = val;

			if( this.type.toUpperCase() == "CHECKBOX" )
				this.checked = ((parseInt(val)==1)?true:false);
		}

		return this;
	},
	GetTextValue: function()
	{
		return this.innerText;
	},
	SetTextValue: function(val)
	{
		this.innerText = val;
		return this;
	},
	SetHTML: function(val)
	{
		this.innerHTML = val;
		return this;
	},
	HasClassName: function(sClassName)
	{
		var e = this;
		var eClassName = e.className;

		return (eClassName.length > 0 && (eClassName == sClassName ||
			new RegExp("(^|\\s)" + sClassName + "(\\s|$)").test(eClassName)));
	},
	SetClassName: function(sClassName)
	{
		var e = this;
		if (!e.HasClassName(sClassName))
		  e.className += (e.className ? ' ' : '') + sClassName;

		return e;
	},
	RemoveClassName: function(sClassName)
	{
		var e = this;
		e.className = e.className.replace(
			new RegExp("(^|\\s+)" + sClassName + "(\\s+|$)"), ' ').Strip();

		return e;
	},
	SetStyle: function(Styles)
	{
		var e = this;
		var eStyle = e.style;

		if (Ds.IsString(Styles))
		{
			e.style.cssText += ';' + Styles;
			
			if( Styles.Include('opacity') )
				e.SetOpacity(Styles.match(/opacity:\s*(\d?\.?\d*)/)[1]);
		}
	    
		for (var prop in Styles)
		{
			if (prop == 'opacity')
				e.SetOpacity(Styles[prop]);
			else
				eStyle[(prop == 'float' || prop == 'cssFloat') ?
					(Ds.IsUndefined(eStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
					prop] = Styles[prop];
		}

		return e;
	},
	SetOpacity: function(Value) /* Rehacer teniendo en cuenta IExplorer Filters */
	{
		var e = this;
		e.style.opacity = (Value == 1 || Value == '') ? '' :
		  (Value < 0.00001) ? 0 : Value;
		return e;
	},
	// -- Final
	__dummy: 0
}

// ------------------------------------
// --- Eventos

Ds.Event.Methods = 
{
	// -- PreventDefault 
	PreventDefault: function()
	{
		if (Ds.IsNullOrUndefined(this.preventDefault))
			this.returnValue = false;
		else
			this.preventDefault();

	  return this;
	},
	// -- Final
	__dummy: 0
}

// ------------------------------------
// --- Ajax

Ds.Ajax.DefOptions = 
{
	OnDone:       null,
	Url:          "",
	Async:        false,
	MimeType:     "text/plain",
	ResponseText: "",
	Data:         ""
};

Ds.Ajax.Methods = 
{
	// -- PreventDefault 
	Create: function(Opts)
	{
		this.Request = null;
		Ds.Extend(this, Ds.Ajax.DefOptions.Or(Opts));
		
		return this;
	},
	CreateRequest: function()
	{
		// --- Crear objeto subyacente
		if (window.XMLHttpRequest)
		{ 
			this.Request = new XMLHttpRequest();

			if (this.Request.overrideMimeType)
				this.Request.overrideMimeType(this.MimeType);
		}
		else
		{
			var progIDs = [ 'Msxml2.XMLHTTP', 'Microsoft.XMLHTTP' ];
			
			for ( var i = 0; i < progIDs.length; i++ )
			{
				try
				{
					this.Request = new ActiveXObject(progIDs[i]);
					return this;
				}
				catch (ex) {}
			}
		}
	},
	Submit: function(sData)
	{
		this.CreateRequest();
		
		this.Request.onreadystatechange = this.OnGetResponse.Bind(this);
		this.Request.open( 'POST', this.Url, this.Async );
		this.Request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		
		if( null != sData )
			this.Data = sData;

		this.Request.setRequestHeader('Content-Length', sData.length);
		this.Request.send(this.Data);
	},
	OnGetResponse: function()
	{
		if( (this.Request.readyState == 4) && (this.Request.status == 200) )
		{
			this.ResponseText = this.Request.responseText;
			if( null != this.OnDone )
				this.OnDone(this, this.Request);
		}
	},
	// -- Final
	__dummy: 0
};

// ------------------------------------
// --- Extensiones a Object
Ds.Extend(Object.prototype, {
	Or: function(o)
	{
		Ds.Extend(this,o);
		return this;
	}
});

// ------------------------------------
// --- Extensiones a String
Ds.Extend(String.prototype, {
	Strip: function()
	{
		return this.replace(/^\s+/, '').replace(/\s+$/, '');
	},
	Trim: function() {
		return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
	},
	Include: function(Pattern)
	{
		return this.indexOf(Pattern) > -1;
	}
});


// ------------------------------------
// --- Extensiones a Function
Ds.Extend(Function.prototype,
{
	Bind: function(o)
	{
		var __Method = this, Obj = o; //arguments[0];
	    return function() {	return __Method.apply(Obj);	}
	}
});

