
// values of submitTargetOfActionPopup: this value can be set by any
//  action that creates a form in a popup. its value indicates
// where the result of a succesful submit should go
// - BODYDIV => displayInBodyDiv
// - ACTIONDIV => displayInActionPopupDiv
// - ROWUPDATE => addOrUpdateRow
// (unsuccessful submits will offer the form again in the popup
//
// a popup as a result of a select => will open its own popup
// and the result of a successful submit will always be an update
// of the select field 

// note javascript 'global' variable is attached to window
// BODYDIV is the default submitTarget (when doing a 'new', the
// form is assuming that the submitTarget has the value BODYDIV)
var lastSubmitTargetOfActionPopup = 'BODYDIV';
var lastActionTableId = null;
var lastSelectId = null;
var actionPopupDivDraggable = null;
var selectPopupDivDraggable = null;

// COMMON ROLES
function submitChangePasswordJs(){
  var map = { oldPassword:null, newPassword:null, newPassword2:null };
  dwr.util.getValues(map);
  DwrLc.submitChangePassword(map, submitCallback);
  setSavingString();
}



////////////////////////////////////////////////////////////////////
// generic functions

function getSubmitTarget(){
	if(popupExists('SELECTPOPUPDIV')){
		return 'SELECTUPDATE';
	}else{
		return lastSubmitTargetOfActionPopup;
	}
}

function prepareSelectPopupForm(selectId){
//  lastSubmitTarget = 'SELECTUPDATE';
  createSelectPopup(selectId);
  lastSelectId = selectId;
  setLoadingString('SELECTPOPUPDIV'); 
}

function prepareActionPopupForm(submitTarget, id, actionTableId){
  lastSubmitTargetOfActionPopup = submitTarget;
  if(actionTableId != '0' && actionTableId != 'agendaTable'){
    clearAndHighlightRowById(actionTableId, id);  	
  }
  createActionPopup(actionTableId, id);  
  lastActionTableId = actionTableId;     
  setLoadingString('ACTIONPOPUPDIV');
}

function prepareActionPopupDisplay(id, actionTableId){
  if(actionTableId != '0' && actionTableId != 'agendaTable'){
    clearAndHighlightRowById(actionTableId, id);    
  }
  createActionPopup(actionTableId, id);
  setLoadingString('ACTIONPOPUPDIV'); 
}

function cancelForm(){
	// assume cancel comes from top form, this can
	// be incorrect, but the resulting behaviour is not too bad
  if(popupExists('SELECTPOPUPDIV')){
    deletePopup('SELECTPOPUPDIV');
  }else if(popupExists('ACTIONPOPUPDIV')){
    deletePopup('ACTIONPOPUPDIV');
  }else{
    displayInBodyDiv("");    
  }
}

function submitCallback(stringList){
	// data is a list of strings
	// first string: indicates the submitTarget OR '*FORMAGAIN' in case of unsuccessful submit
	if(stringList[0] == 'ACTIONFORMAGAIN'){
		if(popupExists('ACTIONPOPUPDIV')){
      displayInActionPopupDiv(stringList[1]);			
		}else{
      displayInBodyDiv(stringList[1]);     			
		}
	}else if(stringList[0] == 'SELECTFORMAGAIN'){
		if(popupExists('SELECTPOPUPDIV')){
      displayInSelectPopupDiv(stringList[1]);			
		}else{
      //ignore: the popup might have been closed in the mean while  			
		}
	}else if(stringList[0] == 'BODYDIV'){
		deletePopup('ACTIONPOPUPDIV');// if it exists
		deletePopup('SELECTPOPUPDIV');// if it exists (could happpen at error)
    displayInBodyDiv(stringList[1]);
    lastSubmitTargetOfActionPopup = 'BODYDIV';
	}else if(stringList[0] == 'ROWUPDATE'){
		deletePopup('ACTIONPOPUPDIV');
		// multiple new rows can be returned
		for(var i=1;i+1<stringList.length;i=i+2){
      addOrUpdateRow(stringList[i], stringList[i+1]); // rowId, content
		}
    lastSubmitTargetOfActionPopup = 'BODYDIV';
	}else if(stringList[0] == 'ACTIONPOPUPDIV'){
    displayInActionPopupDiv(stringList[1]);
    lastSubmitTargetOfActionPopup = 'BODYDIV';
	}else if(stringList[0] == 'SELECTUPDATE'){
		deletePopup('SELECTPOPUPDIV');
    addOptionToSelect(stringList[1], stringList[2]); // value, label
	}else if(stringList[0] == 'ROWDELETE'){
		deletePopup('ACTIONPOPUPDIV');
    deleteRow(stringList[1]); // rowId
    lastSubmitTargetOfActionPopup = 'BODYDIV';
	}else{
	  alert('Unexpected state '+ lastSubmitTargetOfActionPopup);
	}
}

function displayInBodyDiv(data){
  dwr.util.setValue('BODYDIV', data, { escapeHtml:false });
//  tabberAutomatic(); // if there are tabs, tabber needs to be restarted
  focusOnFirstInput(document.body);
}

function displayInActionPopupDiv(data){
	displayInPopupDiv('ACTIONPOPUPDIV', data);
}

function displayInSelectPopupDiv(data){
	displayInPopupDiv('SELECTPOPUPDIV', data);
}

function displayInPopupDiv(popupId, data){
  // scriptaculous draggables
  
  var content='<table class="popup"><tr><th id="'+popupId+'Handle" class="popup"></th><th  class="popup" align="right"><a href="#" onclick="deletePopup(\''+popupId+'\'); return false;">X</a></th></tr><tr><td class="popup" colspan="2">'+data+'</td></tr></table>';
  dwr.util.setValue(popupId, content, { escapeHtml:false });

  focusOnFirstInput(document.getElementById(popupId));   
}

// popup functions
function createActionPopup(actionTableId, id){
  var popupDiv = document.createElement('div');
  popupDiv.setAttribute('id', 'ACTIONPOPUPDIV');// to create/delete/drag
//  popupDiv.setAttribute('class', 'popupContainer');

  // determine position, should work with multiple actionTables
  // id is used to determine offset (popup relative to row element)
  var position;
  if(actionTableId == 'agendaTable'){
	var td = document.getElementById(id);
  	if(td != null){
      position = getElementPosition(td);
      position[0] = position[0]-80;
  	}else{
  		// should not happen
      position = [200, 200];    
  	}
  }else{
    var actionTable = document.getElementById(actionTableId);
    if(actionTable != null){
  	  var row = document.getElementById(actionTableId+id);
      if(row != null){
        position = getElementPosition(row);
      }else{
    	  // new object
        position = getElementPosition(actionTable);
        position[0] = position[0]-50;
        position[1] = position[1]+50;
      }
    }else{
      position = [200, 200];    
    } 
  }

  //alert(position[0] +";"+ position[1]);
  popupDiv.style.left = (position[0]+100)+'px';
  popupDiv.style.top = (position[1]-100)+'px';
  popupDiv.style.position = 'absolute';
  popupDiv.style.zIndex = '2';
  document.body.appendChild(popupDiv);
  
  actionPopupDivDraggable = new Draggable('ACTIONPOPUPDIV',{handle:'ACTIONPOPUPDIVHandle'});
}

function createSelectPopup(selectId){
  var popupDiv = document.createElement('div');
  popupDiv.setAttribute('id', 'SELECTPOPUPDIV');
  popupDiv.setAttribute('class', 'popupContainer');

  // determine position, selectId is used to determine offset
  var position;
  var select = document.getElementById(selectId);
  if(select != null){
    position = getElementPosition(select);
  }else{
    alert('Unknown selectId '+selectId);    
  }

  //alert(position[0] +";"+ position[1]);
  popupDiv.style.left = (position[0]+20)+'px';
  popupDiv.style.top = (position[1]-100)+'px';
  popupDiv.style.position = 'absolute';
  popupDiv.style.zIndex = '2';
  document.body.appendChild(popupDiv);  

  selectPopupDivDraggable = new Draggable('SELECTPOPUPDIV',{handle:'SELECTPOPUPDIVHandle'});
}

function popupExists(popupId){
  if(document.getElementById(popupId) == null){
	  return false;
  }else{
  	return true;
  }
}

function deletePopup(popupId){
  if(selectPopupDivDraggable != null){
    selectPopupDivDraggable.destroy();
  }
  if(actionPopupDivDraggable != null){
  	actionPopupDivDraggable.destroy();
  }
  var popupDiv = document.getElementById(popupId);
  if(popupDiv != null){
    popupDiv.parentNode.removeChild(popupDiv);
  }
}

// action table manipulation

// highlight row
function highlightRow(row){
  row.style.backgroundColor = '#dde899';
//  row.setAttribute('style','background-color:#dde899');does not work in IE
}

function clearAndHighlightRowById(actionTableId, id){
    //clear all other highlights
    var table = document.getElementById(actionTableId);
    var rowList = table.getElementsByTagName('tr');
    for(var i = 0; i<rowList.length;i++){
      var row = rowList[i];
      row.removeAttribute('style');
    }

    if(id != '0'){
      // rowId=actionTableId+id
      var row = document.getElementById(actionTableId+id);
      highlightRow(row);
    }else{
      // global action in actionTable
    }
}

// delete row by id
function deleteRow (rowId) {
  var row = document.getElementById(rowId);
  row.parentNode.removeChild(row);
}

function addOrUpdateRow (rowId, content) {
  var table = document.getElementById(lastActionTableId);
  var row = document.getElementById(rowId);
  if(row != null){
  	// existing row
  	removeAllChildren(row);
  }else{
  	//add a new row
    row = table.tBodies[0].insertRow(-1);
  	row.setAttribute('id', rowId);
    highlightRow(row);
//  	var classOfNewRow;
//  	if(table.lastChild.getAttribute('class') == 'actionTableEvenRow'){
//      classOfNewRow = 'actionTableOddRow';
//  	}else{
//  		classOfNewRow = 'actionTableEvenRow';
//  	}
//  	row.setAttribute('class', classOfNewRow);
  }
	//IE has problem here:innerHtml of row is readOnly
  //  row.innerHTML = content;
  // current workaround is to parse the content and add cell by cell
  // drop first and last tag (<td ...>   </td>)
  // then convert string in array by using separator "</td><td ...>
  // (... to take extra attributes into account)


  var i=-1;
  while(1){
  	i++;
  	// is next cell <td> or <td align="right">
    var td1 = content.indexOf('<td>');
    var td2 = content.indexOf('<td align="right">');
    var endTd = content.indexOf('</td>');
    if(td1==-1 && td2==-1){
    	// no new cell 
    	break;
    }else if((td2 >-1 && td2<td1) || td1==-1){
    	// right aligned
    	var cellContent = content.substring(td2+18,endTd);
//      alert(cellContent);
    	content = content.substring(endTd+5);
      var cell = row.insertCell(i);
      cell.innerHTML = cellContent;
      cell.setAttribute('align','right');
    }else{
    	// default aligned
      var cellContent = content.substring(td1+4,endTd);
//      alert(cellContent);
      content = content.substring(endTd+5);
      var cell = row.insertCell(i);
      cell.innerHTML = cellContent;
    }
//    alert(content);
  }

//  var gtLocation = content.indexOf('>');
//  content = content.substring(gtLocation+1);
//  content = content.substring(0, content.length-5);
//  //TODO: if last cell is empty, IE does not return the last element
//  var cellArray = content.split(/<\/td><td*>/);
//  for(var i=0;i<cellArray.length;i++){
//    var cell = row.insertCell(i);
//    cell.innerHTML = cellArray[i];
//  }
}

function addOptionToSelect(value, text){
  var select = document.getElementById(lastSelectId);

  var option = new Option(text, value, false, true);
  
  var optionLength = select.length;
  // remember the new option
  var newOption = select.options[optionLength-1];
  newOption.selected = false;
  select.options[optionLength-1] = option;
  select.options[optionLength] = newOption;
}

// helper functions
function setLoadingString(divId){
  setString(divId, 'Loading');
}

function setSavingString(divId){
  setString(divId, 'Saving');
}

function setString(divId, message){
  dwr.util.setValue(divId, '<h2>'+message+'</h2>', { escapeHtml:false });       
}

function removeAllChildren(ele){
  var child = ele.firstChild;
  var next;
  while (child != null) {
    next = child.nextSibling;
    ele.removeChild(child);
    child = next;
  }
}

// pass the HTML element and return the x, y position
function getElementPosition(element){
  var left=element.offsetLeft;
  var top=element.offsetTop;
  var parent;
  while(element.offsetParent!=null){
    parent=element.offsetParent;
    left+=parent.offsetLeft;
    top+=parent.offsetTop;
    element=parent;
  }
  return [left,top];
}

// focus on first input child element of given element
function focusOnFirstInput(element){
	// TODO
	// disabled this focus function, because it still gave
	// a focus error with bciCheckOutForm (fragment in fragement)
	// another reason for disabling it is that only forms loaded
	// by dwr are calling it, so forms loaded via normal http didn't
	// get focus
	// => look for better solution that handles above problems, maybe in form itself?
//  if(element != null){
//    var inputList = element.getElementsByTagName("input");
//    // skip elements on which one can not focus => better
//    // and also IE will complain by a popup
//    for(var i=0;i<inputList.length;i++){
//      var inputElement = inputList.item(i);
//      	// also check whether display style of parent divs is 'block'
//      	alert(inputElement.type+': '+inputElement.style.display);
//      if(inputElement.type == 'text' && inputElement.disabled == false && inputElement.style.display != "none"){      	
//    	  inputElement.focus();
//    	  break;
//      }
//    }
//  }
}


// support functions for formObjects => TODO: put in separate file

// formBooleanWithFragment
function toggleDivDisplayJs(divId){
	var div = document.getElementById(divId);
	if(div.style.display == 'none'){
    div.style.display = 'block';
  }else{
    div.style.display = 'none';
  }
}

// formStringWithOptionsWithFragment
function displaySelectedDivJs(fieldName){
//	alert(fieldName);
	// get container div
  var containerDiv = document.getElementById(fieldName+'Div');
  var select = document.getElementById(fieldName);
  if(select == null){
  	select = myGetElementsByName("select", fieldName)[0];
  }
	// get all divs in this containerDiv
  var divList = myGetElementsByName("div", fieldName+'DivChild');
//	alert(divList.length);
	for(var i = 0; i<divList.length;i++){
    var div = divList[i];
    // order in divList is order in which divs appear in document which
    // is the order of the options in the select box
//    alert('div.id '+div.id);
    if(select.selectedIndex == i){
//    	alert('set div as block '+ div.id + ' '+i);
      div.style.display = 'block';
    }else{
      div.style.display = 'none';
    }
  }	
}

// formStringWithOptionsAndNew & formIdObjectAndNew
function getFormWhenNew(getFormCommonJs, selectId){
	// is the new option selected (always last one)?
  var select = document.getElementById(selectId);
  if(select.selectedIndex == select.length-1){
//  	alert(selectId);
  	prepareSelectPopupForm(selectId);
//  	alert(getFormCommonJs);
  	getFormCommonJs('0', displayInSelectPopupDiv);  	
//    alert('3');
  }
}

//formStringWithOptionsAndUpdateOther (& formIdObjectAndUpdateOther)
function updateOtherField(selectId, targetActionList, targetIdOrNameList){
  //	alert(selectId);
  // get current selected value
  var select = document.getElementById(selectId);
  var currentValue = select.options[select.selectedIndex].value;

  var nbrOfFields = targetActionList.length;
  // i know this is not optimal, but as long as it's only 1 or 2 parameters
  for(var i=0;i<nbrOfFields;i++){
    DwrCc.getSelectData(selectId, currentValue, targetActionList[i], targetIdOrNameList[i], selectCallback);
  
    // set 'updating' text depending on target
    // risk that the server response is quicker than this thread => stuck on 'Updating'
    if(targetActionList[i] == 'UPDATESELECTOPTIONS'){
      var select = document.getElementById(targetIdOrNameList[i]);
      if(select == null){
        select = myGetElementsByName("select", targetIdOrNameList[i])[0];
      }  
      // remove all options
      select.length=0;
      select.options[0] = new Option('Updating', 'Updating',false,false);
    }else if(targetActionList[i] == 'UPDATETAGCONTENT'){
      dwr.util.setValue(targetIdOrNameList[i], 'Updating', { escapeHtml:false });    
    }else if(targetActionList[i] == 'UPDATEATTRIBUTE'){
      var field = document.getElementById(targetIdOrNameList[i]);
      if(field == null){
        field = myGetElementsByName("input", targetIdOrNameList[i])[0];
      }
      field.setAttribute('value', 'Updating'); // this assumes updated attribute is 'value'  	
    }
  }
}

function selectCallback(stringList){
	if(stringList[0] == 'UPDATESELECTOPTIONS'){
    var select = document.getElementById(stringList[1]);
    if(select == null){
      select = myGetElementsByName("select", stringList[1])[0];
    }
  
    // remove all options
    select.length=0;
  
    // note: setting html options in select with setValue does not work
    var nbrOfNewOptions = (stringList.length-2)/2;
    for(var i=0;i<nbrOfNewOptions;i++){
  	  var option = new Option(stringList[i*2+3], stringList[i*2+2],false,false);
  	  select.options[select.length] = option;
    }
	}else if(stringList[0] == 'UPDATETAGCONTENT'){
    dwr.util.setValue(stringList[1], stringList[2], { escapeHtml:false });   	
  }else if(stringList[0] == 'UPDATEATTRIBUTE'){
    var field = document.getElementById(stringList[1]);
    if(field == null){
      field = myGetElementsByName("input", stringList[1])[0];
    }
    //TODO:after dragging the popup, the update of type UPDATEATTRIBUTE does not seem to work anymore (string values are still ok), weird?
  	field.setAttribute(stringList[2], stringList[3]);
	}else{
		alert('Not supported selectTargetAction '+ stringList[0]);
	}
}

// selectAll/selectNone (used in FormStringWithOptionsArray
function selectAll(fieldName){
	checkboxList = myGetElementsByName("input", fieldName);
	var nbrOfCheckboxes = checkboxList.length;
  for(var i=0;i<nbrOfCheckboxes;i++){
    var checkbox = checkboxList[i];
    checkbox.checked = true;
  }		
}

function selectNone(fieldName){
	checkboxList = myGetElementsByName("input", fieldName);
	var nbrOfCheckboxes = checkboxList.length;
  for(var i=0;i<nbrOfCheckboxes;i++){
    var checkbox = checkboxList[i];
    checkbox.checked = false;
  }		
}

// IE does not implement getElementsByName correctly, so we
// need to do it ourselves (with a little help of our friends
// at http://www.dreamincode.net/code/snippet293.htm)
function myGetElementsByName(tag, name){
  var elem = document.getElementsByTagName(tag);
  var arr = new Array();
  for(i = 0,iarr = 0; i < elem.length; i++) {
    att = elem[i].getAttribute("name");
    if(att == name) {
      arr[iarr] = elem[i];
      iarr++;
    }
  }
  return arr;
}

// trick to delete the popup of a form that does a http request
// onclick="deletePopup()" does not work because it is removing the form too fast
function deleteActionPopupDelayed(){
	setTimeout("deletePopup('ACTIONPOPUPDIV')", 2000);
}

// used in agenda to scroll to current time
// can be used more general: it will scroll in any page to the element with id 'scrollToId'
function scrollToElement(){
      var element = document.getElementById("scrollToId");
      
	  var selectedPosX = 0;
	  var selectedPosY = 0;
	              
	  while(element != null){
//	    selectedPosX += element.offsetLeft;
	    selectedPosY += element.offsetTop;
	    element = element.offsetParent;
	  }
	                        		      
	 window.scrollTo(selectedPosX,selectedPosY);

	}
