/********
GOOEYTABLE - update, add and delete table rows with AJAX
********/
function getGTElements(e){
  g_table = e.findElement('table')
  g_row   = e.findElement('tr')
  
  gtelements  = {
    'g_image':    e.findElement('img'),
    'g_cell':     e.findElement('td'),
    'g_form':     e.findElement('form'),
    'g_table':    $(g_table),
    'g_row':      $(g_row),
    'db_row_id':  g_row.id.gsub((g_table.id + '_row_'), ''),
    'model_name': g_table.id
  };
  return gtelements;
}

function handleRailsErrors(errors, model_name) {
  err_arr = response.errors.gsub(/[\[\]"]/, '').split(",");
  if (err_arr.length > 1){
    return_error  = []
    err_msg       = '<h2>Errors</h2><ul>';
    err_arr.each(function(error, i){
      if (i%2 == 1) err_msg += '<li>'+error+'</li>';
    })
    err_msg += '</ul>';
    errorExplanation    = document.createElement('div');
    Element.extend(errorExplanation);
    errorExplanation.id = 'gtExplanation';
    errorExplanation.update(err_msg);
    $(model_name+'_gooeytable_errors').insert(errorExplanation);
  } else {
    return false;
  }
}

function clearRailsErrors(model_name) {
  $(model_name+'_gooeytable_errors').update('');
}

function doEdit(e) {
  gtes  = getGTElements(e);
  clearRailsErrors(gtes.model_name);
  
  // remove existing form inputs
  gtes.g_form.getInputs().each(function(input_elm, i) {
    if (input_elm.id == 'gooey_input_id') {
      input_elm.remove();
    }
    if (input_elm.hasClassName('gooeytable_cell')) {
      i_str = input_elm.parentNode.readAttribute('original_val');
      input_elm.parentNode.innerHTML  = i_str;
    }
  })
  // revert existing images to edit buttons
  $$('.ok_button').invoke('remove');
  $$('.edit_button').each(function(button, i) {
	  button.firstDescendant().show();
  });
  
  // get cells that can be updated
  g_cells = gtes.g_row.descendants().findAll(function(d){
    return (d.hasClassName('button_field') != true) && (d.tagName == 'TD') && (d.readAttribute('ginput_none') != 'true');
  })
  // convert data td content to inputs
  g_cells.each(function(cell, i){
    input_name      = cell.readAttribute('name');
    ginput_size     = cell.readAttribute('ginput_size');
    i_str           = '<input type="text" id="'+input_name+'"'
    i_str           +=' name="'+gtes.model_name+'['+input_name+']"'
    i_str           +=' value="'+cell.readAttribute('original_val')+'"'
    i_str           +=' class="gooeytable_cell"'
    if (ginput_size != null) i_str +=' style="width: '+ginput_size+'"'
    i_str           +=' />';
    cell.innerHTML  = i_str;
  })
  // hide edit button, add ok button
  gtes.g_image.hide();
  var ok_image        = document.createElement('img');
  Element.extend(ok_image);
  ok_image.className  = 'ok_button';
  ok_image.src        = '/images/button_ok_s.png';
  ok_image.observe('click', doUpdate)
  gtes.g_cell.insert(ok_image);
  
  // add id input to form
  var id_input    = document.createElement('input');
  Element.extend(id_input);
  id_input.name   = 'id';
  id_input.id     = 'gooey_input_id';
  id_input.type   = 'hidden';
  id_input.value  = gtes.db_row_id;
  gtes.g_form.insert(id_input);
  
  // update form action
  gtes.g_form.action = 'update_' + gtes.model_name;
  
}

function doUpdate(e) {
  gtes  = getGTElements(e);
  clearRailsErrors(gtes.model_name);
  
  // send update
  gtes.g_form.request({
    onSuccess: function(t) {
      response = t.responseText.evalJSON(true);
      handleRailsErrors(response.errors, gtes.model_name);
      
      // get cells that can be updated
      g_cells = gtes.g_row.descendants().findAll(function(d){
        return (d.hasClassName('button_field') != true) && (d.tagName == 'TD');
      })
      // revert cells to display
      g_cells.each(function(cell){
        field_name  = cell.readAttribute('name')
        field_value = response.inst[field_name]
        cell.writeAttribute('original_val', field_value);
        cell.innerHTML  = field_value;
      })
      $('gooey_input_id').remove();
      $$('.ok_button').invoke('remove');
      $$('.edit_button').each(function(button, i) {
      	  button.firstDescendant().show();
      });
    }
  });
  
}

function doAdd(e) {
  gtes  = getGTElements(e);
  clearRailsErrors(gtes.model_name);
  
  // remove existing form inputs
  gtes.g_form.getInputs().each(function(input_elm, i) {
    if (input_elm.id == 'gooey_input_id') {
      input_elm.remove();
    }
    if (input_elm.hasClassName('gooeytable_cell')) {
      i_str = input_elm.parentNode.readAttribute('original_val');
      input_elm.parentNode.innerHTML  = i_str;
    }
  })
  // revert existing images to edit buttons
  $$('.ok_button').invoke('remove');
  $$('.edit_button').each(function(button, i) {
	  button.firstDescendant().show();
  });
  
  // update form action
  gtes.g_form.action = 'create_' + gtes.model_name;
  // send create
  gtes.g_form.request({
    onSuccess: function(t) {
      response = t.responseText.evalJSON(true);
      if (response.message == 'not added') {
        handleRailsErrors(response.errors, gtes.model_name);
      } else {
        // clear add form inputs
        gtes.g_form.getInputs().invoke('clear');
      
        // copy last row
        row_count   = gtes.g_table.tBodies[0].rows.length;
        new_row     = gtes.g_table.tBodies[0].rows[0].cloneNode(true);
        Element.extend(new_row);
        new_row.id  = gtes.model_name+'_row_'+response.inst.id;
      
        // update row class
        new_row.removeClassName('rowalt_even');
        new_row.removeClassName('rowalt_odd');
        if (row_count%2 == 0) {
          new_row.className = 'rowalt_even';
        } else {
          new_row.className = 'rowalt_odd';
        }
      
        // deal with cells
        new_row.descendants().each(function(cell, i){
          Element.extend(cell);
          if ((cell.hasClassName('button_field') != true) && (cell.tagName == 'TD')) {
            field = cell.readAttribute('name');
            cell.update(response.inst[field]);
            cell.writeAttribute('original_val', response.inst[field]);
          }
          // Add observer methods
      		if (cell.hasClassName('edit_button')) {
        	  cell.firstDescendant().observe('click', doEdit);
      	  }
      	  if (cell.hasClassName('delete_button')) {
        	  cell.firstDescendant().observe('click', doDelete);
      	  }
      
        })
      
        // insert row into table
        gtes.g_table.tBodies[0].insert(new_row, 'bottom');
        /************************
        // TODO: re-sort on insert 
        ************************/
      }
    }
  });
}
function doDelete(e) {
  gtes        = getGTElements(e);
  clearRailsErrors(gtes.model_name);
  
  delete_url  = 'destroy_'+gtes.model_name+'?id='+gtes.db_row_id;
  // send delete
  new Ajax.Request(delete_url, {
    onSuccess: function(t) {
      response = t.responseText.evalJSON(true);
      
      // remove row from table
      gtes.g_row.remove();
      
      // update rows classnames
      for (var i = 0; i < gtes.g_table.tBodies[0].rows.length; i++) {
        row = $(gtes.g_table.tBodies[0].rows[i].id);
        row.removeClassName('rowalt_even');
        row.removeClassName('rowalt_odd');
        if (i%2 == 0) {
          row.addClassName('rowalt_even');
        } else {
          row.addClassName('rowalt_odd');
        }
      }
      
    }
  });
}

function doDefault(e) {
  gtes        = getGTElements(e);
  clearRailsErrors(gtes.model_name);
  
  default_url  = 'default_'+gtes.model_name+'?id='+gtes.db_row_id;
  // send delete
  new Ajax.Request(default_url, {
    onSuccess: function(t) {
      response = t.responseText.evalJSON(true);
      
      // update other rows default states (all to false)
      $$('#'+gtes.g_table.id+' .default_button').each(function(button, i) {
    	  button.firstDescendant().src  = '/images/cancel_s.png';
  	  });
      
      // update default state of image
      gtes.g_image.src  = '/images/button_ok_s.png';
    }
  });
  
}

var GooeyTable = Class.create({
  initialize: function(elm) {
    var self;
    this.elm  = elm;
    table_id  = this.elm.id
		all_rows  = $A($(table_id).rows);
		
		// Add observer methods
		$$('.edit_button').each(function(button, i) {
  	  button.firstDescendant().observe('click', doEdit);
	  });
	  $$('.delete_button').each(function(button, i) {
  	  button.firstDescendant().observe('click', doDelete);
	  });
	  $$('.add_button').each(function(button, i) {
  	  button.firstDescendant().observe('click', doAdd);
	  });
	  $$('.default_button').each(function(button, i) {
  	  button.firstDescendant().observe('click', doDefault);
	  });
  }
});



// Add methods on load
var gooeytables = new Array();
Event.observe(window, 'load', function() {
	// Get all gooeytables on this page:
	domTables  = $$('.gooeytable');
	domTables.each(function(dt, i) {
	  newGooeyTable   = new GooeyTable(dt);
	  gooeytables[i]  = newGooeyTable;
	});

});