
document.freezed_old_state = '';
document.boxes_only1_or_full_div_nodes = {};


function smart_replace(old_node_id, new_node) {

  var old_node = document.getElementById(old_node_id);

  // Se gia' presente nel dom, lo rimpiazzo li' (tanto il puntatore
  // nell'hash boxes_div_nodes punta comunque al dom), altrimenti lo
  // rimpiazzo solo in boxes_div_nodes, perche' evidentemente e' un
  // hidden box. Nel primo caso uso poi la ricorsione per riempirlo
  // sostituendo gli eventuali aj_init poiche' la pagina deve essere
  // renderizzata, nel secondo caso invece lo lascio only1 e ci
  // pensera' lo smart_replace che lo inserisce nella pagina a
  // riempirlo. Considerando che nell'hash viene gia' rimpiazzato da
  // aj_actions, nel caso in cui non sia visibile (cioe' non e'
  // presente nel dom) semplicemente non eseguo nulla.
  if (!old_node) return;

  var father = old_node.parentNode;
  father.replaceChild(new_node, old_node);

  var aj_init_elements = new_node.getElementsByTagName('div');
  
  for (var i = 0; i < aj_init_elements.length; i++) {

    var aj_element = aj_init_elements[i];

    var id = aj_element.getAttribute('id');
    var name = aj_element.getAttribute('name');

    // div non gestiti da AJ_env
    if ( (name != 'aj_init') ) continue; 

    var next_new_node = document.boxes_only1_or_full_div_nodes[id];

    smart_replace(id, next_new_node);

  }
}


function aj_actions(actions, path) {

  var getHash = true;
  var params = Form.serialize(document, getHash);

  var hash_request = {};
  hash_request.mode = 'web_service';
  hash_request.actions = Object.toJSON(actions);
  hash_request.params = Object.toJSON(params);
  hash_request.freezed_old_state = document.freezed_old_state;

  if (!path) {path = '';}

  var a =
      new Ajax.Request(
		       document.URL + path, {
			 
			 'asynchronous': false,
			 'method': 'post',
			 'parameters': hash_request,
			 'evalScripts' : true,

			 onSuccess: function(r) {

			 var response = r.responseText;

			 var reply = response.evalJSON();

			 document.freezed_old_state = reply.freezed_old_state;
			 var reply_boxes_only1_html = reply.boxes_only1_html;
			 var deleted_boxes_ids = reply.deleted_boxes_ids;

			 for (var box_id in reply_boxes_only1_html) {
			     var box_only1_html = 
				 reply_boxes_only1_html[box_id];

			     var tmp_node = document.createElement('div');
			     tmp_node.innerHTML = box_only1_html;

			     var divs = tmp_node.getElementsByTagName('div');
			   
			     var new_node = divs[0];
			   
			     document.boxes_only1_or_full_div_nodes[box_id] =
				 new_node;
			 }

			 var external_boxes_ids = reply.external_boxes_ids;
			 for (var i = 0; i < external_boxes_ids.length; i++) {
			     var external_box_id = external_boxes_ids[i];
			     
			     var new_node = 
				 document.boxes_only1_or_full_div_nodes[external_box_id];

			     smart_replace(external_box_id, new_node);
			 }

			 for (var box_id in reply_boxes_only1_html) {

			     var greppeds = external_boxes_ids.grep(box_id);
			     var grepped = greppeds[0];
			     if (grepped) continue;
			   
			     var new_node = 
			     document.boxes_only1_or_full_div_nodes[box_id];
			   
			     smart_replace(box_id, new_node);
			 }

			 for (var i = 0; i < deleted_boxes_ids.length; i++) {
			     var deleted_box_id = deleted_boxes_ids[i];
			     
			     delete(document.boxes_only1_or_full_div_nodes[deleted_box_id]);
			     
			 }

		       },

		       onFailure: function(r) {

			 alert('Internal Server Error');

		       }
		     }
		     );
}

function aj_actions_no_error(actions, path) {

  var getHash = true;
  var params = Form.serialize(document, getHash);

  var hash_request = {};
  hash_request.mode = 'web_service';
  hash_request.actions = Object.toJSON(actions);
  hash_request.params = Object.toJSON(params);
  hash_request.freezed_old_state = document.freezed_old_state;

  if (!path) {path = '';}

  var a =
      new Ajax.Request(
		       document.URL + path, {
			 
			 'asynchronous': false,
			 'method': 'post',
			 'parameters': hash_request,
			 'evalScripts' : true,

			 onSuccess: function(r) {

			 var response = r.responseText;

			 var reply = response.evalJSON();

			 document.freezed_old_state = reply.freezed_old_state;
			 var reply_boxes_only1_html = reply.boxes_only1_html;
			 var deleted_boxes_ids = reply.deleted_boxes_ids;

			 for (var box_id in reply_boxes_only1_html) {
			     var box_only1_html = 
				 reply_boxes_only1_html[box_id];

			     var tmp_node = document.createElement('div');
			     tmp_node.innerHTML = box_only1_html;

			     var divs = tmp_node.getElementsByTagName('div');
			   
			     var new_node = divs[0];
			   
			     document.boxes_only1_or_full_div_nodes[box_id] =
				 new_node;
			 }

			 var external_boxes_ids = reply.external_boxes_ids;
			 for (var i = 0; i < external_boxes_ids.length; i++) {
			     var external_box_id = external_boxes_ids[i];
			     
			     var new_node = 
				 document.boxes_only1_or_full_div_nodes[external_box_id];

			     smart_replace(external_box_id, new_node);
			 }

			 for (var box_id in reply_boxes_only1_html) {

			     var greppeds = external_boxes_ids.grep(box_id);
			     var grepped = greppeds[0];
			     if (grepped) continue;
			   
			     var new_node = 
			     document.boxes_only1_or_full_div_nodes[box_id];
			   
			     smart_replace(box_id, new_node);
			 }

			 for (var i = 0; i < deleted_boxes_ids.length; i++) {
			     var deleted_box_id = deleted_boxes_ids[i];
			     
			     delete(document.boxes_only1_or_full_div_nodes[deleted_box_id]);
			     
			 }

		       }
		     }	
		     );
}			


// Ho tolto la distinzione fra actions e replace per evitare di dover
// decidere lato client se rimpiazzare o no un box, decisione il piu'
// delle volte possibile solo lato server per effettuare prima la
// verifica dei dati immessi. Percio' il replace avviene in maniera
// spontanea semplicemente restituendo un box che ha lo stesso id di
// quello precedente che va a rimpiazzare. Per il lato server occorre
// pero' che un'action richiami l'inizializzatore. Tale action deve
// essere eseguita sul box che deve essere rimpiazzato. Questa potra'
// effettuare tutti i controlli del caso e infine se vi sono le
// condizioni richiamare un inizializzatore che generi un ambiente e
// lo restituisca. La reply in modo web_service di solito invoca la
// action su un box e non ottiene nulla in uscita: in questo caso
// otterra' un oggetto box_set e potra' quindi capire che non deve
// invocare box_html sul box in questione, il quale si e'
// autoeliminato, ma su tutti i box dell'oggetto box_set che gli e' stato
// restituito (i quali finiscono tutti in refreshed boxes).
// Per il mode init_window, viene spedita una window inizializzante
// (con un focus box di tipo init_box e col link all'AJ_engine.js) ed
// automaticamente eseguita sull'onload un'aj_action init_env che
// richiama l'inizializzatore passato mediante il parametro init.



function aj_upload(id, f_after_upload) {
  
  rand_n = Math.round(Math.random() * 1000000000);

  f_after_upload =
    f_after_upload.replace(/(\)\; return false\;)/,
			   ",'/_upload_" + rand_n + "'$1");

  f = new Function (f_after_upload);
  

  jQuery('#loading_' + id).ajaxStart(function(){jQuery(this).show();});
  jQuery('#loading_' + id).ajaxComplete(function(){jQuery(this).hide();});
  jQuery.ajaxFileUpload({
    url: document.URL + '/' + id + '/' + rand_n,
	fileElementId: id,
	dataType: 'json',
	success: function(data,status){f();},
	error:  function(data,status,e){alert(Object.toJSON(e));}
    });

}

function mvc_action_with_state(box_id, view, action_params, ext) {

    var getHash = true;
    var params = Form.serialize(document, getHash);

    var a = $('aj_form');

    var b = document.createElement('input');
    b.type = 'hidden';
    b.name = 'mode';
    b.value = 'mvc_with_state';
    a.appendChild(b);

    var c = document.createElement('input');
    c.type = 'hidden';
    c.name = 'freezed_old_state';
    c.value = document.freezed_old_state;
    a.appendChild(c);

    var d = document.createElement('input');
    d.type = 'hidden';
    d.name = 'box_id';
    d.value = box_id;
    a.appendChild(d);

    var e = document.createElement('input');
    e.type = 'hidden';
    e.name = 'view';
    e.value = view;
    a.appendChild(e);

    var f = document.createElement('input');
    f.type = 'hidden';
    f.name = 'params';
    f.value = Object.toJSON(params);
    a.appendChild(f);

    var form = $('aj_form');
    form.action = document.URL + ext;
    form.submit();

    Element.remove(b);
    Element.remove(c);
    Element.remove(d);
    Element.remove(e);
    Element.remove(f);

    return;
}
