function getObject(id) { return document.getElementById(id); }

function addFields(div_suffix)
{
   if (!div_suffix) div_suffix='';
   eval ('fieldsCounter'+div_suffix+'++;');
   var fieldsCounter_var = eval('fieldsCounter'+div_suffix);
   if (getObject('fieldsCounter'+div_suffix)) getObject('fieldsCounter'+div_suffix).value++;

	var newFields = getObject('readroot'+div_suffix).cloneNode(true);
	newFields.id = 'din_div_'+fieldsCounter_var;
	newFields.style.display = 'block';
	var newField = newFields.childNodes;
	for (var i=0;i<newField.length;i++)
	{
		var theName = newField[i].id;
		if (theName)
		{
			newField[i].name = theName + fieldsCounter_var;
			newField[i].id   = theName + fieldsCounter_var;
		}
	}
	var insertHere = getObject('writeroot'+div_suffix);
	insertHere.parentNode.insertBefore(newFields,insertHere);
}
function removeLastField(div_suffix)
{
   if (!div_suffix) div_suffix='';
   var fieldsCounter_var = eval('fieldsCounter'+div_suffix);

	obj = getObject('din_div_' + fieldsCounter_var);
	obj.parentNode.removeChild(obj);

   eval('fieldsCounter'+div_suffix+'--;');
   if (getObject('fieldsCounter'+div_suffix)) getObject('fieldsCounter'+div_suffix).value--;
}

/**
 * Obtiene los TRs de una tabla tales que:
 * - Existe un TD en cada TR con un checkbox de name='del|<...>'
 * - Dicho checkbox esta seleccionado
 * @param tBodyId: id del 'table body' (tag TBODY)
 * @return: Array de objetos TR con las características anteriormente comentadas.
 */
function get_trs_to_remove(tBodyId)
{
	delset = new Array();
	trs = document.getElementById(tBodyId).getElementsByTagName('TR');
	for (i = 0; i < trs.length; i++)
	{
		tds = trs[i].getElementsByTagName('TD');
		for (j = 0; j < tds.length; j++)
		{
			objs = tds[j].childNodes;
			for (k = 0; k < objs.length; k++)
			{
				if (objs[k].name)
				{
					flag = objs[k].name.split('|',1).pop();
					if ((flag == 'del') && objs[k].checked) delset.push(trs[i]);
				}
			}
		}
	}
	return delset;
}

var eIndMax = 0;
var gIndMax;

/**
 * Verifica si el TR corresponde a un grupo de elementos.
 * @param object tr: Objeto TR.
 * @return bool: TRUE si el TR corresponde a un grupo de elementos, FALSE en caso contrario.
 */
function trIsGroup(tr)
{
   if (tr.nodeName == 'TR')
   {
      var strs = tr.id.split('.');
      return (strs[0] == "group") && (tr.id.indexOf('-') == -1);
   }
   return false;
}

/**
 * NOTA: Función válida para tablas con la misma estructura que 'mycampaigns' y 'mymicro'.
 * Si se marca/desmarca un checkbox de grupo, marca/desmarca los checkboxes de todos sus elementos.
 * Si se marca un checkbox de elemento.
 *    Si con ello todos los elementos de su grupo quedan marcados, se marca el checkbox del grupo.
 * Si se desmarca un checkbox de elemento.
 *    Se desmarca, si ya no lo estubiera, el checkbox de su grupo.
 * @param object obj: Checkbox clickeado.
 */
function check_group(obj)
{
   if (eIndMax == 0)
   {
      var aux = obj.parentNode.parentNode.id.split('-');
      eIndMax = getObject(aux[0]).getElementsByTagName('TD').length;
      gIndMax = eIndMax - 1;
   }

	if (obj.name.charAt(4) == 'g') /* Si es un grupo */
	{
		ok = false;
		act = obj.parentNode.parentNode.nextSibling;
		while ((act != null) && !ok) /* Mientras haya TRs y no se llegue a un nuevo grupo */
		{
			if (act.nodeName == 'TR')
			{
				tds = act.getElementsByTagName('TD');
				if ((tds[eIndMax] != null) && (checkbox = tds[eIndMax].firstChild) != null)
					checkbox.checked = obj.checked;
				else ok = true;
			}
			act = act.nextSibling;
		}
	}
	else /* Es un elemento */
	{
		ok = true;
		if (obj.checked)
		{
			act = obj.parentNode.parentNode.previousSibling;
			while ((!trIsGroup(act)) && ok)
			{
				if (act.nodeName == 'TR')
				{
					tds = act.getElementsByTagName('TD');
					/* Controlo que el checkbox este seleccionado */
					if (!tds[eIndMax].firstChild.checked) ok = false;
				}
				act = act.previousSibling;
			}
			if (ok)
			{
				grp = act;
				act = obj.parentNode.parentNode.nextSibling;
				while ((act != null) && (!trIsGroup(act)) && ok)
				{
					if (act.nodeName == 'TR')
					{
						tds = act.getElementsByTagName('TD');
						/* Controlo que el checkbox este seleccionado */
						if (!tds[eIndMax].firstChild.checked) ok = false;
					}
					act = act.nextSibling;
				}

				tds = grp.getElementsByTagName('TD');
				/* Marco/desmarco el checkbox del grupo */
				tds[gIndMax].firstChild.checked = ok;
			}
		}
		else
		{
			/* Viajo hacia el TR del grupo */
			act = obj.parentNode.parentNode.previousSibling;
			while (!trIsGroup(act)) act = act.previousSibling;

			tds = act.getElementsByTagName('TD');
			/* Desmarco el checkbox del grupo */
			tds[gIndMax].firstChild.checked = false;
		}
	}
}

/**
 * NOTA: Función válida para tablas con la misma estructura que 'mycampaigns' y 'mymicro'.
 * Oculta/muestra los elementos (TRs) pertenecientes al grupo indicado.
 * @param object obj: Icono de grupo clickeado.
 */
function change_group_visibility(obj)
{
	act = obj.parentNode.parentNode.nextSibling;
	while ((act != null) && (act.nodeName != 'TR'))
		act = act.nextSibling;
	if (act.style.display != "none")
	{
		view = "none";
		fold = "closed";
	}
	else
	{
		view = "";
		fold = "open";
	}
	if (!trIsGroup(act))
	{
   	do
   		if (act.nodeName == 'TR') act.style.display = view;
   	while (((act = act.nextSibling) != null) && (!trIsGroup(act)));
	}
	obj.src = "/pics/" + fold + ".gif";
}

/**
 * Dado un array de radiobuttons, retorna el valor del radiobutton seleccionado.
 * @param array: Array de radiobuttons.
 * @return: Valor asociado al radiobutton seleccionado. De no haberlo, retorna ''.
 */
function getRadioValue(array)
{
	for (i = 0; i < array.length; i++)
		if (array[i].checked) return array[i].value;
	return '';
}

/**
 * Dado un array de radiobuttons, selecciona el radiobutton cuyo valor es el indicado.
 * @param array: Array de radiobuttons.
 * @param value: Valor del radiobutton a seleccionar.
 */
function setRadioValue(array,value)
{
   value = value.toLowerCase();
	for (i = 0; i < array.length; i++)
	{
		if (array[i].value.toLowerCase() == value) array[i].checked = true;
		else array[i].checked = false;
	}
}

/**
 * Dado un objeto select, retorna su objeto option seleccionado.
 * @param array: Objeto select.
 * @param value: (opcional) Si se lo indica, retorna el option asociado a ese valor.
 * @return: Objeto option seleccionado, NULL en caso de error.
 */
function getSelectOption(array,value)
{
   if (value)
   {
      try { value = value.toLowerCase() } catch (ex) { value = value.toString().toLowerCase() } ;
   	for (i = 0; i < array.options.length; i++)
   		if (array.options[i].value.toLowerCase() == value)
   		   return array.options[i];
   }
   else if ((array.selectedIndex >= 0) && (array.selectedIndex < array.options.length))
   	return array.options[array.selectedIndex];
   return null;
}

/**
 * Dado un objeto select, retorna el valor de la opción seleccionada.
 * @param array: Objeto select.
 * @return: Valor asociado a la opción seleccionada.
 */
function getSelectValue(array)
{
   if ((opt = getSelectOption(array)) != null)
   	return opt.value;
   return false;
}

/**
 * Dado un objeto select, retorna el texto de la opción seleccionada.
 * @param array: Objeto select.
 * @param value: (opcional) Si se lo indica, retorna el texto de la opción asociada a ese valor.
 * @return: Texto asociado a la opción seleccionada.
 */
function getSelectText(array,value)
{
   if ((opt = getSelectOption(array,value)) != null)
      return opt.text;
   return false;
}

/**
 * Dado un objeto select, selecciona la opción cuyo valor es el indicado.
 * @param array: Objeto select.
 * @param value: Valor de la opción a seleccionar.
 */
function setSelectValue(array,value)
{
   if ((opt = getSelectOption(array,value)) != null)
      array.selectedIndex = opt.index;
}

/**
 * Dado un objeto select, selecciona la opción cuyo texto es el indicado.
 * @param array: Objeto select.
 * @param value: Texto de la opción a seleccionar.
 */
function setSelectText(array,text)
{
	var ok = false;
	for (i = 0; (i < array.options.length) && !ok; i++)
	{
		if (array.options[i].text == text)
		{
			array.selectedIndex = array.options[i].index;
			ok = true;
		}
	}
}

/**
 * Agrega una nueva opción al objeto select indicado.
 * @param select: Objeto select.
 * @param txt: Texto de la opción a mostrar.
 * @param val: Valor de la opción.
 * @param sel: Booleano que indica si la opción debe estar o no seleccionada.
 */
function addSelectOption(select,txt,val,sel)
{
   select.options[select.length] = new Option(txt,val,false,sel);
}

/**
 * Quita una opción al objeto select indicado.
 * @param select: Objeto select.
 * @param ind: Posición de la opción a eliminar (entre 0 y select.length - 1)
 */
function delSelectOption(select,ind)
{
   select.options[ind] = null;
}

/**
 * Verifica que el string ingresado sea un número natural.
 * @param str: String a verificar.
 * @return: TRUE en caso que 'str' sea un natural, FALSE en caso contrario.
 */
function natural(str)
{
	if (str.length == 0 || str == '0') return false;
	for (i = 0; i < str.length; i++)
		if (str.charAt(i) < '0' || str.charAt(i) > '9')
			return false;
	return true;
}

/**
 * Verifica que el string ingresado sea un número entero.
 * @param str: String a verificar.
 * @return: TRUE en caso que 'str' sea un entero, FALSE en caso contrario.
 */
function integer(str)
{
	if (str.length == 0) return false;
	for (i = 0; i < str.length; i++)
		if (str.charAt(i) < '0' || str.charAt(i) > '9')
			return false;
	return true;
}

/**
 * Verifica que el string ingresado sea una constante de color hexadecimal (#rrggbb).
 * @param str: String a verificar.
 * @return: TRUE en caso que 'str' sea un color, FALSE en caso contrario.
 */
function isColor(color)
{
   return ((color.length == 7) && (color.match("#([0-9a-fA-F]{6})") != null));
}

/**
 * Copia el texto del objeto indicado al portapapeles.
 * (Sólo funciona en Internet Explorer)
 * @deprecated
function ctrlC(obj)
{
	try
	{
	  window.clipboardData.setData("Text",obj.innerHTML);
	}
	catch (ex) { / * No es posible copiar al Portapapeles * / }
}*/

/**
 * Exhibe un cuadro de diálogo con el mensaje indicado.
 * Dicho cuadro se oculta automáticamente luego de 10 segundos o clickeando sobre él.
 * Estructura del cuadro de dialogo:
 *    <div id="div_msg" class="hidden" onclick="this.style.display='none'">
 *     <div id="div_class"> <p id="p_msg"> </p> </div>
 *    </div>
 *
 * @param txt: Texto a mostrar.
 * @param notErrorMsg: Indica si el texto es informativo (true) o de error (false).
 *                     Dependiendo de ello se aplica un class diferente al div div_class (okay o errorm).
 *                     Si no se lo especifica, se asume que el texto es de error.
 * @param errorFocusObj: Id del objeto donde focalizar el documento en caso de error.
 *                       Si no se lo especifica, no se produce ningún intento de focalización.
 */
function showMessage(txt, notErrorMsg, errorFocusObj)
{
   var class_name = notErrorMsg ? "okay" : "errorm";
   getObject('p_msg').innerHTML = txt;
   getObject('div_class').className = class_name;

   var div_msg = getObject('div_msg');
   div_msg.style.position = 'relative';
   div_msg.style.top = '10px';
   div_msg.style.left = '10px';
   div_msg.style.cursor = 'pointer';
   div_msg.style.display = 'block';

   clearTimeout(toutId);
   toutId = setTimeout("getObject('div_msg').style.display = 'none'",10000);

   if (errorFocusObj && (eFO = getObject(errorFocusObj))) eFO.focus();
}
var toutId;

/**
 * Controla que el string ingresado sea un alias válido.
 * Un alias es una cadena con el formato especificado en ALIAS_FORMAT.
 *
 * @param string alias: Cadena a verificar.
 */
function validate_alias(alias,retvalue)
{
   var ALIAS_MAX_CHAR = 17;
   var ALIAS_FORMAT   = "[a-zA-Z]{1," + ALIAS_MAX_CHAR + "}";

   validate_alias_retvalue = retvalue ? true : false;

   if (((match = alias.match(ALIAS_FORMAT)) == null) || (alias != match))
   {
      showMessage("Debe consistir de una secuencia de letras de a lo sumo " + ALIAS_MAX_CHAR + " caracteres.",0,'input_text_nombre');
      if (validate_alias_retvalue) return false;
   }
   else
   {
      LoadURL('../tools/campaign_ajax.php?action=new&c='+alias,'validate_alias_listener');
   }
}
var validate_alias_retvalue;

/**
 * Listener de la llamada ajax de 'validate_alias'.
 */
function validate_alias_listener(ajax_result)
{
   if (ajax_result)
   {
      var result = ajax_result.split('|');
      if (result[0] == 'OK') showMessage('Alias correcto!',true);
      else showMessage('El alias ya existe',0,'input_text_nombre');
      if (validate_alias_retvalue) return (result[0] == 'OK') ? true : false;
   }
}
