/* Sedit 2.0
   Libreria Javascript para editar valores de un Select.
   Los cambios se reflejan del lado del servidor por medio del php sedit.php

   Observaciones:

    - Por el momento solo se puede usar uno por documento.
    Para usar varios habria que crear una clase Sedit o un objeto prototipo
    y establecer una funcion para realizar la configuracion de los parametros

   - Probado en FX y MSIE

   Miguel Trias - Feb 2006

	Extensión:
	- Posibilidad de emplear más de uno por documento.
   El código aquí contenido es empleado internamente por functions.php::draw_sedit(...) y
   no debería ser utilizado de forma externa a esta función.

   Pablo Prieto - Mar 2006
*/

// ---- Configuration ----------------------------------------------------------

// servira para cuando sea posible tener mas de un Sedit por documento
var SEDIT_ID                     = new Array();
var SEDIT_DIV                    = new Array();

// id del select
var SEDIT_SELECT_ID              = new Array();

// script en el server que recibe las acciones por medio del ajax
var SEDIT_SERVER_SCRIPT          = new Array();

// Configuracion de divs de modos de operacion
var SEDIT_SELECT_DIV_ID          = new Array();
var SEDIT_EDIT_DIV_ID            = new Array();
var SEDIT_ADD_DIV_ID             = new Array();

// configuracion de modo REMOVE
var SEDIT_REMOVE_BUTTON_ID       = new Array();
var SEDIT_REMOVE_CONFIRM         = new Array();
var SEDIT_REMOVE_CONFIRM_TXT     = new Array();
var SEDIT_REMOVE_LISTENER_ACTION = new Array();

// configuracion de modo ADD
var SEDIT_ADD_INPUT_ID           = new Array();
var SEDIT_ADD_OK_BUTTON_ID       = new Array();
var SEDIT_ADD_NOK_BUTTON_ID      = new Array();

// configuracion de modo EDIT
var SEDIT_EDIT_BUTTON_ID         = new Array();
var SEDIT_EDIT_INPUT_ID          = new Array();
var SEDIT_EDIT_OK_BUTTON_ID      = new Array();
var SEDIT_EDIT_NOK_BUTTON_ID     = new Array();

// configuracion del option add_option
var SEDIT_USE_ADD_OPTION         = new Array();
var SEDIT_ADD_OPTION_VALUE       = new Array();
var SEDIT_ADD_OPTION_TEXT        = new Array();
var SEDIT_ADD_OPTION_BUTTON_ID   = new Array();

// configuracion del option separator
var SEDIT_USE_SEPARATOR_OPTION   = new Array();
var SEDIT_SEPARATOR_OPTION_ID    = new Array();
var SEDIT_SEPARATOR_OPTION_VALUE = new Array();
var SEDIT_SEPARATOR_OPTION_TEXT  = new Array();

// clase css definida para ocultar elementos
var SEDIT_CSS_CLASS_HIDDEN       = new Array();

// -----------------------------------------------------------------------------

/* Variable global de uso interno */
var Sedit_id = 0;

/**
 * Crea un objeto Sedit y lo retorna.
 * @param select_id: id y name del select.
 * @param server_script: script encargado de atender las solicitudes de alta, baja y edicion de options.
 */
function newSedit(select_id,server_script)
{
	Sedit_id++;

	var id = Sedit_id;

	SEDIT_ID[id]                     = id;
	SEDIT_DIV[id]                    = "sedit_div_"+SEDIT_ID[id];
	SEDIT_SELECT_ID[id]              = select_id;
	SEDIT_SERVER_SCRIPT[id]          = server_script;
	SEDIT_SELECT_DIV_ID[id]          = "sedit_select_div_"+SEDIT_ID[id];
	SEDIT_EDIT_DIV_ID[id]            = "sedit_edit_div_"+SEDIT_ID[id];
	SEDIT_ADD_DIV_ID[id]             = "sedit_add_div_"+SEDIT_ID[id];
	SEDIT_REMOVE_BUTTON_ID[id]       = "sedit_remove_button_"+SEDIT_ID[id];
	SEDIT_REMOVE_CONFIRM[id]         = true;
	SEDIT_REMOVE_LISTENER_ACTION[id] = '';
	SEDIT_ADD_INPUT_ID[id]           = "sedit_add_input_"+SEDIT_ID[id];
	SEDIT_ADD_OK_BUTTON_ID[id]       = "sedit_add_ok_"+SEDIT_ID[id];
	SEDIT_ADD_NOK_BUTTON_ID[id]      = "sedit_add_nok_"+SEDIT_ID[id];
	SEDIT_EDIT_BUTTON_ID[id]         = "sedit_edit_button_"+SEDIT_ID[id];
	SEDIT_EDIT_INPUT_ID[id]          = "sedit_edit_input_"+SEDIT_ID[id];
	SEDIT_EDIT_OK_BUTTON_ID[id]      = "sedit_edit_ok_"+SEDIT_ID[id];
	SEDIT_EDIT_NOK_BUTTON_ID[id]     = "sedit_edit_nok_"+SEDIT_ID[id];
	SEDIT_USE_ADD_OPTION[id]         = true;
	SEDIT_ADD_OPTION_VALUE[id]       = "++";
	SEDIT_ADD_OPTION_BUTTON_ID[id]   = "sedit_add_option_"+SEDIT_ID[id];
	SEDIT_USE_SEPARATOR_OPTION[id]   = true;
	SEDIT_SEPARATOR_OPTION_ID[id]    = "sedit_separator_option_"+SEDIT_ID[id];
	SEDIT_SEPARATOR_OPTION_VALUE[id] = "--";
	SEDIT_SEPARATOR_OPTION_TEXT[id]  = "-----------------";
	SEDIT_CSS_CLASS_HIDDEN[id]       = 'hidden';

	var Sedit = {

		//---- STATES ------------------------------------------------------------

		myId: id,
		prevValue: 0,

		setState: function(state)
		{
		    id = Sedit.myId;

		    if (!state) return false;
		    switch (state)
		    {
		        case 1: // Normal
		           Sedit.changeDisplay(SEDIT_EDIT_DIV_ID[id],0);
		           Sedit.changeDisplay(SEDIT_ADD_DIV_ID[id],0);
	              Sedit.changeDisplay(SEDIT_SELECT_DIV_ID[id],1);
		        break;
		        case 2: // Edicion
		           var opts = Sedit.getObject(SEDIT_SELECT_ID[id]).options;
		           Sedit.getObject(SEDIT_EDIT_INPUT_ID[id]).value = opts[opts.selectedIndex].text;
		           Sedit.changeDisplay(SEDIT_SELECT_DIV_ID[id],0);
                 Sedit.changeDisplay(SEDIT_ADD_DIV_ID[id],0);
		           Sedit.changeDisplay(SEDIT_EDIT_DIV_ID[id],1);
	              Sedit.getObject(SEDIT_EDIT_INPUT_ID[id]).focus();
		        break;
		        case 3: // Agregar
		           Sedit.changeDisplay(SEDIT_SELECT_DIV_ID[id],0);
		           Sedit.changeDisplay(SEDIT_EDIT_DIV_ID[id],0);
		           Sedit.changeDisplay(SEDIT_ADD_DIV_ID[id],1);
		        break;
		    }
		},

		setStateNormal : function ()
		{
		    id = Sedit.myId;

		    Sedit.setState(1);
		    Sedit.getObject(SEDIT_EDIT_INPUT_ID[id]).value='';
		},

		setStateEdit   : function ()
		{
		    id = Sedit.myId;

		    if (
		            Sedit.getObject(SEDIT_SELECT_ID[id]).value!=SEDIT_ADD_OPTION_VALUE[id]
		         && Sedit.getObject(SEDIT_SELECT_ID[id]).value!=SEDIT_SEPARATOR_OPTION_VALUE[id]
		       )
		    Sedit.setState(2);
		},

		setStateAdd    : function ()
		{
		    id = Sedit.myId;

		    Sedit.getObject(SEDIT_ADD_INPUT_ID[id]).value='';
		    Sedit.setState(3);
		    Sedit.getObject(SEDIT_ADD_INPUT_ID[id]).focus();
	    },

	    //---- EVENTS LISTENERS -----------------------------------------------------------------------

		addEvent : function (elm, evType, fn, useCapture)
		{
		    id = Sedit.myId;

		    if (elm.addEventListener)
		    {
	    		elm.addEventListener(evType, fn, useCapture);
	    		return true;
		    } else if (elm.attachEvent) {
	    		var r = elm.attachEvent('on'+evType, fn);
	    		return r;
		    } else {
	    		elm['on'+evType] = fn;
		    }
		},

		//---- EDIT -----------------------------------------------------------------------------------

		onEditOK : function()
		{
		    id = Sedit.myId;

	        var edit_value = Sedit.getObject(SEDIT_EDIT_INPUT_ID[id]).value;
	        var edit_key   = Sedit.getObject(SEDIT_SELECT_ID[id]).value;
	        url = SEDIT_SERVER_SCRIPT[id] + '?sedit_action=sedit_edit&sedit_edit_value='+edit_value+'&sedit_edit_key='+edit_key;
	        LoadURL(url, 'sedit_'+id+'.onEditCallback');
		},
		onEditCallback: function(ajax_result)
		{
         id = Sedit.myId;

         if (ajax_result!='')
         {
            var reply = ajax_result.split('-');
            if ( reply[0]=='OK' )
            {
               var opts = Sedit.getObject(SEDIT_SELECT_ID[id]).options;
                opts[opts.selectedIndex].text = Sedit.getObject(SEDIT_EDIT_INPUT_ID[id]).value;
            }
         }
         Sedit.setStateNormal();
		},
		onEditNOK : function()
		{
		    id = Sedit.myId;

		    Sedit.setStateNormal();
		},

		//---- ADD -------------------------------------------------------------------------------------

		onAddOK : function()
		{
		    id = Sedit.myId;

	        var new_value = Sedit.getObject(SEDIT_ADD_INPUT_ID[id]).value;
	        if ( new_value!='' )
	        {
	            var url = SEDIT_SERVER_SCRIPT[id] + '?sedit_action=sedit_add&sedit_new_value='+new_value;
	            LoadURL(url, 'sedit_'+id+'.onAddCallback');
	        }
		},
		onAddCallback : function(ajax_result)
		{
         id = Sedit.myId;

         if ( ajax_result!='' )
         {
            var reply = ajax_result.split('-');
            if (reply[0]=='OK')
            {
               Sedit.addOption(SEDIT_SELECT_ID[id], Sedit.createOption(Sedit.getObject(SEDIT_ADD_INPUT_ID[id]).value,reply[1]), true);
               Sedit.getObject(SEDIT_SELECT_ID[id]).value=reply[1];
               Sedit.prevValue = reply[1];
            }
         }
         Sedit.setStateNormal();
		},
		onAddNOK : function()
		{
		    id = Sedit.myId;

		    if (Sedit.prevValue == SEDIT_ADD_OPTION_VALUE[id] || Sedit.prevValue == 0)
		       Sedit.prevValue = SEDIT_SEPARATOR_OPTION_VALUE[id];

		    Sedit.getObject(SEDIT_SELECT_ID[id]).value=Sedit.prevValue;
		    Sedit.setStateNormal();
		},

		//---------------------------------------------------------------------------------------------

		onRemove : function()
		{
		    id = Sedit.myId;

		    if
		    (
	               Sedit.getObject(SEDIT_SELECT_ID[id]).value!=SEDIT_ADD_OPTION_VALUE[id]
	            && Sedit.getObject(SEDIT_SELECT_ID[id]).value!=SEDIT_SEPARATOR_OPTION_VALUE[id]
		    )
		    {
	    	    if (SEDIT_REMOVE_CONFIRM[id])
	    	       if (!confirm(SEDIT_REMOVE_CONFIRM_TXT[id]))
	    	           return;
	            var url = SEDIT_SERVER_SCRIPT[id] + '?sedit_action=sedit_remove&sedit_remove_value='+Sedit.getObject(SEDIT_SELECT_ID[id]).value;
	            LoadURL(url, 'sedit_'+id+'.onRemoveCallback')
		    }
		},
		onRemoveCallback : function(ajax_result)
		{
		    id = Sedit.myId;

		    if ( ajax_result!='')
		    {
	           if ( ajax_result == 'OK' )
	           {
		           var value = Sedit.getObject(SEDIT_SELECT_ID[id]).value;
		           Sedit.getOption(SEDIT_SELECT_ID[id],value,1);
		           eval(SEDIT_REMOVE_LISTENER_ACTION[id]);
	           }
		    }
		},

		//---------------------------------------------------------------------------------------------

		onSeparator : function ()
		{
		    id = Sedit.myId;

		    Sedit.getObject(SEDIT_SELECT_ID[id]).value=Sedit.prevValue;
		},

	    onSelectChange : function()
	    {
		    id = Sedit.myId;

	        var value = Sedit.getObject(SEDIT_SELECT_ID[id]).value;

	        if ( value==SEDIT_SEPARATOR_OPTION_VALUE[id] )
	        {
	            Sedit.onSeparator();
	            return;
	        }
	        if ( value==SEDIT_ADD_OPTION_VALUE[id] )
	        {
	            Sedit.setStateAdd();
	            return;
	        }
	        Sedit.prevValue = Sedit.getObject(SEDIT_SELECT_ID[id]).options[Sedit.getObject(SEDIT_SELECT_ID[id]).selectedIndex].value;
	    },

		init : function ()
		{
		    id = Sedit.myId;

			// sets separator option and "add" option
			if (SEDIT_USE_ADD_OPTION[id])
			{
   			if (SEDIT_USE_SEPARATOR_OPTION[id])
   			{
   				Sedit.addOption(SEDIT_SELECT_ID[id],Sedit.createOption(SEDIT_SEPARATOR_OPTION_TEXT[id],SEDIT_SEPARATOR_OPTION_VALUE[id],SEDIT_SEPARATOR_OPTION_ID[id]));
   			}
 	         Sedit.addOption(SEDIT_SELECT_ID[id],Sedit.createOption(SEDIT_ADD_OPTION_TEXT[id],SEDIT_ADD_OPTION_VALUE[id],SEDIT_ADD_OPTION_BUTTON_ID[id]));
			}

			// setEventsListeners
			// No funca en IE
			Sedit.addEvent(Sedit.getObject(SEDIT_SELECT_ID[id]),'change', Sedit.onSelectChange, false);
			Sedit.addEvent(Sedit.getObject(SEDIT_REMOVE_BUTTON_ID[id]),'click', Sedit.onRemove, false);
			Sedit.addEvent(Sedit.getObject(SEDIT_EDIT_BUTTON_ID[id]),'click', Sedit.setStateEdit, false);
			Sedit.addEvent(Sedit.getObject(SEDIT_EDIT_OK_BUTTON_ID[id]),'click', Sedit.onEditOK, false);
			Sedit.addEvent(Sedit.getObject(SEDIT_EDIT_NOK_BUTTON_ID[id]),'click', Sedit.onEditNOK, false);
			Sedit.addEvent(Sedit.getObject(SEDIT_ADD_OK_BUTTON_ID[id]),'click', Sedit.onAddOK, false);
			Sedit.addEvent(Sedit.getObject(SEDIT_ADD_NOK_BUTTON_ID[id]),'click', Sedit.onAddNOK, false);

		    // sets initial state to normal
		    Sedit.setState(1);
		},

	    //---- auxiliar -------------------------------------------------------------------------------------

		getObject: function(obj_id)
		{
		    id = Sedit.myId;

			return document.getElementById(obj_id);
		},

		changeDisplay: function(obj_id,value)
		{
		    id = Sedit.myId;

		    if (value==null) value=0;

	        var str_stack  = ' ' + Sedit.getObject(obj_id).className + ' ';
	        var str_needle = ' ' + SEDIT_CSS_CLASS_HIDDEN[id] + ' ';

			switch (value)
			{
			    case 0:
			    case false:
			      if ( str_stack.indexOf(str_needle) == -1 )
	                Sedit.getObject(obj_id).className = Sedit.getObject(obj_id).className +' ' +SEDIT_CSS_CLASS_HIDDEN[id];
			    break;

			    case 1:
			    case true:
			      if ( str_stack.indexOf(str_needle) != -1 )
			      {
			          var pattern = new RegExp( SEDIT_CSS_CLASS_HIDDEN[id] );
			          Sedit.getObject(obj_id).className = Sedit.getObject(obj_id).className.replace(pattern,'') ;
			      }
			    break;
			}
		},

		getTarget: function(e)
		{
		    id = Sedit.myId;

			if ( e && e.target )
				target = e.target;
			if ( window.event && window.event.srcElement )
				target = window.event.srcElement;
			if ( !target )
				return false;
			return target
		},

		getOption: function (selectId,valor,remove)
		{
		    id = Sedit.myId;

			if (!valor) return false;
			var comboOptions = Sedit.getObject(selectId).options;
			for ( i=0 ; i<comboOptions.length; i++ )
			{
				if ( comboOptions[i].value==valor )
				{
					ret = comboOptions[i];
					if (remove) {
					    ret = Sedit.createOption (comboOptions[i].text,comboOptions[i].value,comboOptions[i].id);
					    comboOptions[i] = null;
					}
					return (ret);
				}
			}
		},

		addOption: function (selectId, opt, notInLastPlace)
		{
		    id = Sedit.myId;

			if (!opt) return false;

			var options = Sedit.getObject(selectId).options;

			if (notInLastPlace==1)
			{

			   if (SEDIT_USE_SEPARATOR_OPTION[id])
			      var OptSeparator = Sedit.getOption(SEDIT_SELECT_ID[id],SEDIT_SEPARATOR_OPTION_VALUE[id],1);
			   var OptAdd       = Sedit.getOption(SEDIT_SELECT_ID[id],SEDIT_ADD_OPTION_VALUE[id],1);

			   options[options.length] = opt;

			   if (SEDIT_USE_SEPARATOR_OPTION[id])
			      options[options.length] = OptSeparator;
			   options[options.length] = OptAdd;

			}else{
			   options[options.length] = opt;
			}
		},

		createOption: function(text, value, opt_id)
		{
		    id = Sedit.myId;

			var opt = new Option (text, value);
			if (opt_id) opt.id=opt_id;
			return opt;
		}

	}
	return Sedit;
}
