var cacheMethod = {};
var ppce_cache = {};

Prototype.Exeption = {
	handle: function(e,func,clas) {
	var message; 	
		if (Object.isUndefined(e.description)){
			if (e != ''){
				message = e;
			}
		}
		else {
			if	(e.description != '') {
				message = e.description;
			}
		}
		if (message != ''){
			if (clas) message = 'Clase: '+clas+"\n" + message;
			if (func) message = 'Funcion: '+func+"\n" + message;
			alert(message);
		}
	}
};

// Going to defunct....
addEvent = function(obj,type,fn) {
	if (obj != null)
	{
		if ( obj.attachEvent)
		{
			obj['e'+type+fn] = fn;
			obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
			obj.attachEvent( 'on'+type, obj[type+fn] );
		}
		else
		{
			obj.addEventListener( type, fn, false );
		}
	}
}
// Watch for this funccion and replace it whith element.observe -=Fray=-

removeEvent=function(obj, type, fn){
var r;
	if (obj.detachEvent)
	{
		r = obj.detachEvent( 'on'+type, obj[type+fn] );
		obj[type+fn] = null;
	}
	else
	{
		r = obj.removeEventListener( type, fn, false );
	}
	return r;
}

getElementsByNameLike = function(name) {
var	salida = [];
var	todos = document.getElementsByTagName("*");
	for(var i=0,t=todos.length;i<t;i++){
		try{
			if(todos[i].getAttribute('name').indexOf(name) >= 0){
				salida[salida.length] = todos[i];
			}
		}catch(e){}
	}
	return salida;
}

getElementsByIdLike=function(name,tag,type){
var salida = [];
var todos;
	if(type != null)
	{
		todos = document.getElementsByTagName(tag);
	}
	else
	{
		todos = document.getElementsByTagName('*');
	}
	for(var i=0,t=todos.length;i<t;i++)
	{
		if (type != null)
		{
			if (todos[i].type == type)
			{
				if(todos[i].id.indexOf(name) >= 0)
				{
					salida[salida.length] = todos[i];
				}
			}
		}
		else
		{
			if(todos[i].id.indexOf(name) >= 0)
			{
				salida[salida.length] = todos[i];
			}
		}
	}
	return salida;
}

//	DEVUELVE UN ARRAY CON TODOS LOS ELEMENTOS CON UN NOMBRE DADO.
function $N(element) {
	if (Object.isString(element))
		return $A(document.getElementsByName(element)).each(
			function (elmnt){
				elmnt = Element.extend(elmnt);
			}
		);
}

function $$c(selectors){
	if (typeof selectors === 'string') {
		if (ppce_cache[selectors] === undefined) {
			ppce_cache[selectors] = $$(selectors);
		}
		return ppce_cache[selectors];
	}
	else {
		return ppce_cache[selectors.join('')] || $$(selectors);
	}
	
}

function $NL(element) {
	if (Object.isString(element))
		return $A(getElementsByNameLike(element)).each(
			function (elmnt){
				elmnt = Element.extend(elmnt);
			}
		);
}

Object.extend(Date.prototype, {
	addSeconds: function( i ){
		this.setSeconds( this.getSeconds() + i );
		return this;
	}
	,removeSeconds: function (i) {
		this.setSeconds( this.getSeconds() - i );
		return this;
	}
	,addDays: function (i) {
		this.setDate( this.getDate() + i );
		return this;
	}
	,addMonths: function(i) {
		this.setMonth(this.getMonth() + i ) ;
		return this;
	}
	,addYears: function (i) {
		this.setFullYear(this.getFullYear() + i);
		return this;
	}
  ,addWorkingDays: function (interval) {
		while ((this.getDay() === 0) || (this.getDay() === 6) || interval-- > 0){
			this.setDate(this.getDate()+1);
		}
		return this;
	}
  ,removeWorkingDays: function (interval) {
		while ((this.getDay() === 0) || (this.getDay() === 6) || interval-- > 0){
			this.setDate(this.getDate()-1);
		}
		return this;
	}
  ,toSeconds: function () {
		return this.getSeconds() + this.getMinutes()*60 + this.getHours()*60*60;
	}
  ,toDbFHString: function () {
    return this.getFullYear() + '-' + (this.getMonth() + 1) + '-' + this.getDate() + ' ' + this.getHours() + ':' + this.getMinutes() + ':' + this.getSeconds();
  }
  ,toDbFString: function () {
    return this.getFullYear() + '-' + (this.getMonth() + 1) + '-' + this.getDate();
  }
  ,toDbHString: function () {
    return this.getHours() + ':' + this.getMinutes() + ':' + this.getSeconds();
  }
  ,isZero: function () {
    var zero = new Date(0,0,0,0,0,0,0);
    return (this.getTime() == zero.getTime());
  }
  ,cada_dia_segun_: function (rango, fn, ambito) {  // Itera por las fechas hasta el fin del rango solicitado.
    var currDay = new Date(this);
    if (rango == 'semana') {
      do {
        fn.call(ambito, new Date(currDay));
        currDay.addDays(1);
      } while (currDay.getDay() != 0);
    }
    else if (rango == 'quincena') {
      for(var i = 0; i < 2; i++) {
        do {
          if (currDay.getDay() != 0)
            fn.call(ambito, new Date(currDay));
          
          currDay.addDays(1);
        } while (currDay.getDay() != 0);//&& currDay.getMonth() == this.getMonth()
      }
    }
    else if (rango == 'mes') {
      do {
        fn.call(ambito,new Date(currDay));
        currDay.addDays(1);
      } while (currDay.getMonth() == this.getMonth());
    }
    else if (rango == 'anio') {
      do {
        fn.call(ambito,new Date(currDay));
        currDay.addDays(1);
      } while (currDay.getYear() == this.getYear());
    }
  }
});

Element.addMethods({
	atr: function(element, attrib){
		if (typeof element === 'string') element = $(element);
		return element.getAttribute(attrib) || null;
	}
	,getElementsByIdLike: function(element,id,tag,type){
	var salida = [];
	var todos;
		if(type != null)
			todos = element.getElementsByTagName(tag);
		else
			todos = element.getElementsByTagName('*');

		for(var i=0,t=todos.length;i<t;i++){
			if (type != null){
				if (todos[i].getAttribute('type') == type){
					if(todos[i].id.indexOf(id) >= 0){
						salida[salida.length] = todos[i];
					}
				}
			}
			else{
				if(todos[i].id.indexOf(id) >= 0){
					salida[salida.length] = todos[i];
				}
			}
		}
		return salida;
	},
	getElementsByNameLike: function(element, name){
	var	salida = [];
	var	todos = $(element).getElementsByTagName("*");
		for(var i=0,t=todos.length;i<t;i++){
			try{
				if(todos[i].getAttribute('name').indexOf(name) >= 0){
					salida[salida.length] = $(todos[i]);
				}
			}catch(e){}
		}
		return salida;
	},
	getElementsByName: function(element, name){
	var	salida = [];
	var	todos = $(element).getElementsByTagName("*");
		for(var i=0,t=todos.length;i < t;i++)
		{
			if(todos[i].getAttribute('name') == name)
			{
				salida[salida.length]=todos[i];
			}
		}
		return salida;
	},
	getElementByName: function(element, name){
	var	todos = $(element).getElementsByTagName("*");
		for(var i=0,t=todos.length;i < t;i++){
			if(todos[i].getAttribute('name') == name){
				return todos[i];
			}
		}
		
	},
	makeDivParent: function (element) {
	var	root = new Element('div');
		$(root).insert(element);
		return root;
	},
	replaceNode: function(element, nodo){
		element.parentNode.replaceChild(nodo,element);
	},
	removeNode: function(element, removeChildren) {
		if(removeChildren)
		{
			return $(element).parentNode.removeChild($(element));
		}
		else
		{	
		var	range=document.createRange();
			range.selectNodeContents($(element));
			return $(element).parentNode.replaceChild(range.extractContents(),$(element));
		}
	},
	//	BUSCA TODOS LOS ELEMENTOS HIJOS DE element Y REEMPLAZA SUS VALORES POR LOS DEL json.
	updateFields: function (element,json) {
		element.descendants().each (
			function (elmnt) {
				if (!(Object.isUndefined(json.get(elmnt.getAttribute('name'))))) {
					if (/(span)|(tr)|(td)/.test(elmnt.tagName.toLowerCase())) {
						elmnt.update(json.get(elmnt.getAttribute('name')));
					}
					else if (/(input)|(textarea)/.test(elmnt.tagName.toLowerCase())) {
						elmnt.setValue(json.get(elmnt.getAttribute('name')));
					}
				}
			}
		);
	},
	makeSafe: function (element) {
	//	Hace el elemento inocuo para todos los fines de identificacion.
		element.select('*').each(
			function(elmnt) {
				if (elmnt.id)
					elmnt.removeAttribute('id');
			}
		);
		return element;
	},
	inoculate: function (element) {
	//	Hace el elemento inocuo para todos los fines de identificacion.
		element.select('*').each(
			function(elmnt) {
				if (elmnt.id)
					elmnt.setAttribute('id_c', elmnt.id);
					elmnt.removeAttribute('id');
			}
		);
		return element;
	},
	oculate: function (element) {
	//	Hace el elemento inocuo para todos los fines de identificacion.
		element.select('*').each(
			function(elmnt) {
					elmnt.id = elmnt.getAttribute('id_c');
					elmnt.removeAttribute('id_c');
			}
		);
		return element;
	},
	carvingInStone: function (element) {
	//	Escribe en piedra todos los objetos editables.
	//	habria que verificar si element no tienen hijos y es solo el el que hay que petrificar.
		element.select("*").each (
			function(elmnt) {
				if (elmnt.tagName.toLowerCase() === 'input' && elmnt.type.toLowerCase() != 'hidden') {
				var	e_spn = new Element("SPAN",{
							//id: 'spn_' + elmnt.id 
							name: 'spn_' + elmnt.id 
					});
					e_spn.update(elmnt.value);
					
					e_spn.insert(
						new Element("INPUT",{
								 id:	elmnt.id 
								,name:	elmnt.id  
								,type:	'hidden'
								,value:	elmnt.value
						})
					);
				var parent = elmnt.up();
					//elmnt.removeNode(true);
					//elmnt.remove();
					//delete(elmnt);
					//parent.insert(e_spn)
					elmnt.replace(e_spn);
				}
				if (elmnt.tagName.toLowerCase() === 'a') {
					elmnt.removeAttribute('href');
				}
			}
		);
		return element;
	},
	toHTML: function(element) { 
		if (typeof element=='string') element = $(element);  // IE needs that check with XML 
		return Try.these( 
			function() { 
			var	xmlSerializer = new XMLSerializer(); 
				return  element.nodeType == 4 ? element.nodeValue :	xmlSerializer.serializeToString(element); 
			}, 
			function() { 
				return element.xml || element.outerHTML || $(element).clone().wrap().up().innerHTML; 
			} 
		) || ''; 
	},
	getStyles: function(element) { 
		element = $(element); 
		return $A(element.style).inject({}, function(styles, styleName) { 
			styles[styleName.camelize()] = element.getStyle( styleName ); 
			return styles; 
		} ); 
	}
	,swapWith: function(element, other) {
		element = $(element);
		other = $(other);
		if (element !== other) {
		var	stub = document.createElement('div');
			other = Element.replace(other, stub);
			element = Element.replace(element, other);
			stub = Element.replace(stub, element);
			stub = null;
		}
		return element;
	}
	,containerScrollTo: function (element) {
	//	HACE SCROLL HASTA EL ELEMENTO DENTRO DE SU CONTENEDOR HACIBLE DE SER SCROLLEABLE.
	
	}
	,val: function (element, value, dec) {
		element = $(element);
	var tag = element.tagName.toUpperCase();

		if (Object.isUndefined(value)) {
		//LEYENDO VALORES...
			value = element.value || element.innerHTML;
		}
		else {
			element.writeAttribute("numeric_value", +value);	
			if (!(Object.isUndefined(dec)))
				value = +value.format(dec);

			//SETEANDO VALORES...
			if (tag === 'SPAN' || tag === 'DIV')
				value = element.update(value);
			else
				element.value = value;
			
		}
		return value;
	}
/*

	,fval: function (element, value, dec) {
		element = $(element);
	var tag = element.tagName.toUpperCase();

		if (Object.isUndefined(value)) {
			if (tag === 'SPAN' || tag === 'DIV')
				value = element.innerHTML;
			else
				value = element.value;
			value = (+value).format(dec);
		}
		else {
			element.r_val(value);
			value = (+value).format(dec);
			element.val(value);
		}
		return value || '';
	}
	,r_val: function (element) {
		element = $(element);
		var salida = element.readAttribute("numeric_value") || element.value || element.innerHTML; 	
		return salida;
	}
*/
}); 

Hash.addMethods({
   justData: function (){
      var data = {};
      this.each(
         function(o){
            if (typeof o.value != 'function') data[o.key] = o.value;
         }
      );
      return data;
   }
});


Object.extend(String.prototype, {
	capitalizeWords: function(){
	var str = this;
	var	w = str.split(/\ /);
		w.each(function(wrd){
			return wrd.substr(0,1).toUpperCase()+wrd.substr(1).toLowerCase();
		});
		str = w.join(' ');
	},
	escapeUnicode: function(){
		this.replace(/á/, '\u00e1');
		this.replace(/é/, '\u00e9');
		this.replace(/í/, '\u00ed');
		this.replace(/ó/, '\u00f3');
		this.replace(/ú/, '\u00fa');
		this.replace(/Á/, '\u00c1');
		this.replace(/É/, '\u00c9');
		this.replace(/Í/, '\u00cd');
		this.replace(/Ó/, '\u00d3');
		this.replace(/Ú/, '\u00da');
		this.replace(/ñ/, '\u00f1');
		this.replace(/Ñ/, '\u00d1');
		this.replace(/ü/, '\u00FC');
		this.replace(/Ü/, '\u00DC');
		this.replace(/ç/, '\u00E7');
		this.replace(/Ç/, '\u00C7');
		this.replace(/¿/, '\u00BF');
		this.replace(/¡/, '\u00A1');
		return this;
	}

	,makeElement: function () {
	var	root = new Element('div');
		root.insert(this);
	//	alert(root.toHTML());
		return root.down();
	},

	elementize: function() {
	var	str = this;
	var	range = document.createRange();
		return range.createContextualFragment(str);
	}, 

	toDate: function(){

    if (cacheMethod.hasOwnProperty(this)){
      return new Date(cacheMethod[this]);
    } 
    else {
      var ano = mes = dia= hora= min = seg = 0;
      if (/([0-9]{4})(\/|\-)(0?[0-9]|1[012])(\/|\-)(3[01]|[12][0-9]|0?[0-9])/.test(this)) {
        // AÑO-MES-DIA
        dia = +RegExp.$5;
        mes = +RegExp.$3 == 0?0:(+RegExp.$3-1);
        ano = +RegExp.$1;
      }
      else if (/(3[01]|[12][0-9]|0?[0-9])(\/|\-)(0?[0-9]|1[012])(\/|\-)(([0-9]{4}))/.test(this)){
        // DIA-MES-AÑO
        dia = +RegExp.$1;
        mes = +RegExp.$3 == 0?0:(+RegExp.$3-1);
        ano = +RegExp.$5;
      }

      if (/(\d{1,2})\:(\d{1,2})\:(\d{1,2})/.test(this)) {
        hora= RegExp.$1;
        min	= RegExp.$2;
        seg = RegExp.$3;
      }

			cacheMethod[this] = new Date(ano,mes,dia,hora,min,seg,0);
      return new Date(cacheMethod[this]);
    }
  },
  

	toFloat: function(){
		return +(+this).toFixed(4);
	},

	chomp: function(){
		if (/^\s*(.+)\s*$/.test(this))
			return RegExp.$1;
		else
			return this;
	}	
});

Element.addMethods('iframe', {
	iframe_doc: function(element) {
	  element = $(element);
	  if (element.contentWindow)
		  return element.contentWindow.document;
	  else if (element.contentDocument)
		  return element.contentDocument;
	  else
		  return null;
	},

	$: function(element, frameElement) { 
	  element = $(element);
	  var frameDocument = element.iframe_doc();
	  if (arguments.length > 2) {
		  for (var i = 1, frameElements = [], length = arguments.length; i < length; i++)
			  frameElements.push(element.$(arguments[i]));
		  return frameElements;
	  }
	  if (Object.isString(frameElement))
		  frameElement = frameDocument.getElementById(frameElement);
	  return frameElement || element;
	}

	,$$: function(element, frameElement) { 
		element = $(element);
	var	frameDocument = element.iframe_doc();
		return $A(frameDocument.querySelectorAll(frameElement)).map(Element.extend) || element;
	}
});

Object.extend(Number.prototype, (function() {
	function format(dec, miles) {
	var	num = this, signo=3, expr;
	var cad = new String(this);
	var ceros = "", pos, pdec, i;
		for (i=0; i < dec; i++)
			ceros += '0';
		pos = cad.indexOf('.')
		if (pos < 0)
			cad = cad+"."+ceros;
		else {
			pdec = cad.length - pos -1;
			if (pdec <= dec) {
				for (i=0; i< (dec-pdec); i++)
					cad += '0';
			}
			else {
				num = num*Math.pow(10, dec);
				num = Math.round(num);
				num = num/Math.pow(10, dec);
				cad = new String(num);
			}
		}
		pos = cad.indexOf('.')
		if (pos < 0) pos = cad.length
		if (cad.substr(0,1)=='-' || cad.substr(0,1) == '+') signo = 4;
		if (miles && pos > signo)
			do {
				expr = /([+-]?\d)(\d{3}[\.\,]\d*)/
				cad.match(expr)
				cad=cad.replace(expr, RegExp.$1+','+RegExp.$2)
			}
		while (cad.indexOf(',') > signo)
			if (dec<0) cad = cad.replace(/\./,'')
		return cad;
	}
	
	function toFloat(){
		return isNaN(this)? 0 :+this.toFixed(4);
	}
	
	return {
		format: format,
		toFloat: toFloat
	};
})());


/*
 * Orginal: http://adomas.org/javascript-mouse-wheel/
 * prototype extension by "Frank Monnerjahn" <themonnie@gmail.com>
 */

Object.extend(Event, {
	wheel: function (event){
		var delta = 0;
		if (!event) event = window.event;
		if (event.wheelDelta) {
			delta = event.wheelDelta/120; 
			if (window.opera) delta = -delta;
		} else if (event.detail) { delta = -event.detail/3;	}
		return Math.round(delta); //Safari Round
	}
});
/*
 * enf of extension 
 */ 

Object.extend( Object, {
	unionMege: function ( destino, fuente ) {
    if (!Object.isUndefined(fuente)){
      for (var clave in destino) 
        if ( fuente.hasOwnProperty(clave) ) 
          destino[clave] = fuente[clave];
    }
  }
});

// deprecated, ya viene como método de la clase array.
var _first = function(c){
// funcion iterador que devuelve el primer elemento evaluado.
return true
};

var Loader = {

  Version: '1.8.3',

  require: function(libraryName) {
    try{
      // inserting via DOM fails in Safari 2.0, so brute force approach
      document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
    } catch(e) {
      // for xhtml+xml served content, fall back to DOM methods
      var script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = libraryName;
      document.getElementsByTagName('head')[0].appendChild(script);
    }
  },

  REQUIRED_PROTOTYPE: '1.6.0.3',

  load: function(libs) {
    function convertVersionString(versionString) {
      var v = versionString.replace(/_.*|\./g, '');
      v = parseInt(v + '0'.times(4-v.length));
      return versionString.indexOf('_') > -1 ? v-1 : v;
    }

    var js = /prototype_pcom_extend\.js(\?.*)?$/;
    $$('script[src]').findAll(function(s) {
      return s.src.match(js);
    }).each(function(s) {
      var path = s.src.replace(js, ''),
      includes = (libs)?[0,libs]:s.src.match(/\?.*load=([a-z,_-]*)/);
      (includes ? includes[1] : '').split(',').each( function(include) { 
        Loader.require(path+include+'.js') 
       });
    });
  }
};

Array.prototype.swap=function(a, b)
{
	var tmp=this[a];
	this[a]=this[b];
	this[b]=tmp;
}

function partition(array, begin, end, pivot, fn)
{
	var piv=array[pivot];
	array.swap(pivot, end-1);
	var store=begin;
	var ix;
	for(ix=begin; ix<end-1; ++ix) {
		if(fn(array[ix], piv) < 0) {
			array.swap(store, ix);
			++store;
		}
	}
	array.swap(end-1, store);

	return store;
}

function qsort(array, begin, end, fn)
{
	if(end-1>begin) {
		var pivot=begin+Math.floor(Math.random()*(end-begin));

		pivot=partition(array, begin, end, pivot, fn);

		qsort(array, begin, pivot, fn);
		qsort(array, pivot+1, end, fn);
	}
}

function quick_sort(array, fn)
{
	qsort(array, 0, array.length, fn);
}

