/**
 * File        : Ajax.js
 * Version     : 0.2  
 * Description : mac like Browser
 *               Communication between typo3 via ajax requests, Displaying the 
 *               Toxonomytree, viewing Popups and lots of more usefull stuff..
 * Author      : Dipl. Inf. Hans-Taneli Hamm
 * Date        : 10.11.2006
 * Web         : http://www.pixelmotor.de
 * Copyrights  : 2006 by Pixelmotor  
 **/
 
 /**
  * global Vars 
  */ 
var gDOMID_Browser = "tx_pmtree_pi1_root";  // DOM ID of browser
var gDOMID_BoxPrefix = "tx_pmtree_pi1_browserbox_div_"; // DOM ID prefix for all boxes
var gDOMID_Cart = "tx_pmtree_pi1_list_root"; // DOM ID of Cart
var gHidden = "none"; // style for "hide"
var gBlock = "block"; // style for "show" (block)
var gInline = "inline"; // style for "show (inline)
var gBoxCount = 4; // box count to be shown at once
var gTotalMaxBoxes = 20; // total maximum amount of boxes
var gShowBoxOffset=0; // current Offset of boxes
var gMaxContentBox = -1; // max Content Box (between 1 and gMaxBox)
var gMaxBox = -1; // max Box at all (should Be about gTotalMaxBoxes)
var gSelected = null; // ID of current selected Node or Element
var gTaxonomy=""; // current Taxonomy
var gTaxonomyName= ""; // current Taxonomy Name
var gDatabase=""; // current Database
var gDatabaseName=""; // current Databas Name
var gEmtpyListBoxesCreated=false; // tmp
var gTimeout;  // tmp for timed info window
var win_Detail; // full detail window
var win_Custom=[]; // window list
var gTheme = "alphacube"; // used theme for windows
var gCurrentPath = ""; // current path goes here
var gCurrentPrimaryAccession = ""; // current primary Accession 
var gCurrentOffset = -1; // offset for boxes 
var gDebugOnStart = "no"; // possible values: "yes", "no" & "ask"
var gAccessionNrBoxNr = -1;
var gPathLastBoxNr = -1;
var ajaxRequestURL = "index.php?id=3&type=1"; // oder statt 3 dann halt "Browser"
var ListPageURL = "index.php?id=14"; // oder statt 14 dann halt "List"

/**
 * Internal use to update the gShowBoxOffsetVar and update the path
 * do not modify gShowBoxOffset manually  
 **/ 
function setBoxOffset(i) {
    gShowBoxOffset = i;
    updatePath();  
}

/**
 * Set an Offset to the Tree Boxes * 
 **/ 
function setOffset(i) {  
    setBoxOffset(i);
    updateBoxes();
}

var gDialogWin;
function createDownload(db, dbName, fileFormat) {
    if (!fileFormat) {
	gDialogWin = Dialog.confirm(genTitle("Download")+
				    "Generating download from list for <b>"+
				    dbName+"</b><br>Please select format:", {
					windowParameters: {
					    title: "",
					    className:"alert", width:400},
					okLabel: "arb",
					cancelLabel: "fasta",
					ok:function(win) {
					    getDownloadViaAjax(db, "arb.tgz");
					    document.location = "../download/";
					    return true;
					}, cancel:function(win) {
					    getDownloadViaAjax(db, "fasta.tgz");
					    document.location = "../download/";
					    return true;
					}
				    }
				    );
	return;
    } else {
	getDownloadViaAjax(db, fileFormat);
	document.location = "../download/";
    }
} 

document.observe("dom:loaded", function() {
        $$(".popup").each(function(element) {
		new Tip(element, element.getAttribute("popuptext"), { title: element.getAttribute("popuptitle")});
	});
    });


/**
 * sets a Database
 **/
function setDB(db, dbName) {
    // select correct DB in input form
    var nr = -1;
    var i=0;
    var obj =$("tx_pmtree_pi1_options_form");
    var options = obj["tx_pmtree_pi1[db]"].options;  
    var len=options.length;
    
    for (i=0; i<len; i++) {
	var o = options[i];
	if (o.value == db) {
	    nr = i;
	    break;
	}
    }
    if (nr != -1) {
	options[nr].selected=true;
    }
    
    if (db != gDatabase || dbName!=gDatabaseName) {
	gDatabase = db;
	gDatabaseName = dbName;
	//refreshBrowser();
    }
}

/**
 * sets a Taxonomy
 **/
function setTaxonomy(taxonomy, taxonomyName) {
    // select correct Taxonomy in input form
    var nr = -1;
    var i=0;
    var obj =$("tx_pmtree_pi1_options_form");
    var options = obj["tx_pmtree_pi1[taxonomy]"].options;  
    var len=options.length;
    
    for (i=0; i<len; i++) {
	var o = options[i];
	if (o.value == taxonomy) {
	    nr = i;
	    break;
	}
    }
    if (nr == -1) {
	return;
    }    
    options[nr].selected=true;
    
    if (gTaxonomy != taxonomy || gTaxonomyName != taxonomyName) {
	gTaxonomy = taxonomy;
	gTaxonomyName = taxonomyName;
	//refreshBrowser();
    }
}

/**
 * seekViaAjax () 
 *  opens needed boxes and ask via ajax for content
 *  if jumpto is "true" defines  
 **/ 
function seekViaAjax(id, primaryAccession, taxonomy, taxonomyName, db, dbName, jumpto) {  
    if (taxonomy && taxonomyName) 
	setTaxonomy(taxonomy, taxonomyName);
    if (db && dbName) 
	setDB(db, dbName);
    
    var target = 1; // starting with box zero
    
    // always show the root:
    getNodesViaAjax((-1),(-1), (""), (""), target++, createRootName(), true, true);
    
    var doJumping = (jumpto === true || jumpto === "true");
    if (doJumping) {      
	setOffset(0);
	setMaxContentBox(1); 
	updateBoxes();
    }
    
    // its the root => only view the root element
    if (id=="") return;
    
    var i;
    var path = id.split(";");
    var pid = "";
    var len = path.length-1;
    
    var prAcAvail = primaryAccession!=null && primaryAccession!="";
    
    for (i=0; i<len; i++) {
	pid += path[i] + ";";
	// retreiving the nodes      
	lastnode = ((i+1) < len);
	getNodesViaAjax((-1),(-1), pid, primaryAccession, target++, path[i], true, false);      
    }
    
    if (primaryAccession) {
	// check if we have to view primaryAccession and to open elementslist
	if (target >= gAccessionNrBoxNr) {     
	    // retreiving the elements 
	    getElementsViaAjax(-1, -1, id, primaryAccession, target-1, "", -1, true, true);
	    // retreiving the element info only if we have one to show:
	    var pname = primaryAccession;
	    getDetailViaAjax(-1,-1, id, primaryAccession, target++ , pname, true, true);
	}
    }
    
    if (doJumping) {
	// yey !!! I really like jumping :)
	setMaxContentBox(target-1);
	updateBoxes();
    }
}

/**
 * views Detailed Information from Json Object (which is retreived by Ajax call)
 **/
function viewDetail(json) {  
    var seek = json.data[0].seek == "true";
    
    var target = parseInt(json.data[0].target, 10);
    var id = gDOMID_BoxPrefix + target;
    var tid = targetDetail(gDOMID_BoxPrefix, target);
    
    if (!seek) {    
	setMaxContentBox(target);
    }
    
    var text = json.detail[0].output;
    var wpa = wrap(json.data[0].primaryAccession, "\"");  
    gCurrentPrimaryAccession = json.data[0].primaryAccession;
    gAccessionNrBoxNr = json.data[0].target;
    var pretext = "<p class='title' id='"+json.data[0].target+"'>";
    var sid = tid+"_el_sel";
    var linkName = json.detail[0].organismName;
    var link = 'javascript:changeSelector("'+ sid +'");';  
    pretext += "<span id="+sid+" ";
    pretext += "dataPrimaryAccession='"+json.data[0].primaryAccession+"' ";
    pretext += "dataPID='"+json.data[0].pid+"' ";
    pretext += "dataPName='"+json.detail[0].organismName+"' ";
    pretext += "popupState='element_selected_"+json.data[0].cartState+"' ";
    pretext += "class='checkbox_"+json.data[0].cartState+"'>";
    pretext += makeLink(link, linkName);    
    pretext += "</span>";    
    pretext += "</p>"; 
    
    $(tid).innerHTML = pretext + text;

    new Tip($(sid), {
	ajax: {
		url: ajaxRequestURL
+ "&tx_pmtree_pi1[type]=popup:elementtitle&tx_pmtree_pi1[pid]="
+ escape(json.data[0].pid)
+ "&tx_pmtree_pi1[taxonomy]=" + gTaxonomy
+ '&tx_pmtree_pi1[db]=' + gDatabase
+ "&tx_pmtree_pi1[model]=element_selected_" + json.data[0].cartState
        }
    });
    
    if (!seek) {
	updateBoxes();
    }        
    $(id).addClassName("tx_pmtree_pi1_detail");
    $(id).removeClassName("tx_pmtree_pi1_browserbox");
}

/**
 * generates a title (uses a specific style)
 **/
function genTitle(text) {
    return "<h2>"+text+"</h2>";
}

/**
 * dialog function to confirm things
 * _title : title
 * _text : text to show as message
 * _okFunction : function to be executed if user confirms the dialog
 * _cancelFunction: function to be executed if user cancels the dialog
 * _okLabel : text for the "ok-Button"
 * _cancelLabel: text for the "cancel-Button"  
 **/
function confirm(_title, _text, _okFunction, _cancelFunction, _okLabel, _cancelLabel) {
    var text = genTitle(_title) + _text;
    Dialog.confirm(text, { 
	    windowParameters: {
		className:"alert",
		    width:400 },
		okLabel:     _okLabel, 
		cancelLabel: _cancelLabel, 
		ok:          _okFunction,
		cancel:      _cancelFunction
		});
}

/**
 * Cart actions : add / remove / extend 
 **/
function changeSelector(o) {
    var pid = $(o).getAttribute("dataPID");
    var pname = $(o).getAttribute("dataPName");
    var state = $(o).getAttribute("popupState");
    var primaryAccession = $(o).getAttribute("dataPrimaryAccession");
    switch (state) {
    case "node_selected_none":      
	getCartChangedViaAjax( pid, '', pname, "node", "add", true);
	break;
    case "node_selected_superset":   
	confirm(
		"Info", 
		"Are you sure to override your previous subselection and select all subnodes instead?", 
		function() { 
		    getCartChangedViaAjax( pid, '', pname, "node", "add", true);
		    return true;        
		},null, "override", "cancel");      
	break;
	
    case "node_selected_all":       
	getCartChangedViaAjax( pid, '', pname, "node", "del", true);
	break;
    case "node_selected_subset":
	info("This node is already selected by a supernode. You can not modify this selection.");   
	break;
	
    case "element_selected_none":      
	getCartChangedViaAjax( pid, primaryAccession, pname, "element", "add", true);
	break;    
    case "element_selected_all":       
	getCartChangedViaAjax( pid, primaryAccession, pname, "element", "del", true);
	break;
    case "element_selected_subset":
	info("This sequence-entry is already selected by a supernode. You can not modify this selection.");    
	break;
	
    }
}

/**
 * checks left box for nodes to be tagged
 **/
function checkLeftNeightbour(mynr, idext1, idext2) {
    // CHECK NODES
    var neightbour_div = gDOMID_BoxPrefix + (mynr-1);
    var myself_div = gDOMID_BoxPrefix + (mynr) + idext1;
    var markId;
    var markIdList;
	
    myidList = $(myself_div);
    myidList = myidList.getElementsByTagName("ul");
    if (myidList[0]) {
        myid = myidList[0].id;
        checkList(myid, neightbour_div, idext2);
    }
}

/**
 * checks right box for nodes to be tagged
 **/
function checkRightNeightbour(mynr, idext1, idext2) {
  var myself_div = gDOMID_BoxPrefix + (mynr) ;
  var neightbour_div = gDOMID_BoxPrefix + (mynr+1) + idext1;
  var markId;
  var markIdList;
  
  markIdList = $(neightbour_div);
  markIdList = markIdList.getElementsByTagName("ul");
  if (markIdList[0]) {
      markId = markIdList[0].id;
      checkList(markId, myself_div, idext2);
  }
}

/**
 * checks all nodes throu all used boxes to be tagged or not
 **/
function checkPathConstraints() {
    var idext1 = "_no";
    var idext2 = "_n_"; 
    
    var i;
    for(i=1; i<gMaxContentBox-1;i++) {
	checkRightNeightbour(i, idext1, idext2);
    }

    for(i=1; i<gMaxContentBox;i++) {
	checkLeftNeightbour(i, idext1, idext2);
    }
}

/**
 * checks the nodes left and right from listBas to tag as selected
 **/
function checkList(mark, listBase, idext2) {
    if (!$(listBase)) return;
    var liList = $(listBase).getElementsByTagName('li');
    
    var nodes = $A(liList);
    var i;
    var len = nodes.length;
    for (i=0;i<len;i++) {
	node = nodes[i];
	
        var name;
	name = node.firstChild.innerHTML;
        
        if (name==mark) {
          openID(listBase+idext2+(i+1));
        } else {
	    closeID(listBase+idext2+(i+1));
        }
    }
}

/**
 * Views all Elements in the Box
 */ 
function viewElements(t) {
  var json = eval(t.responseText);
  var selectedElement = null;    
  var numTotalElements = json.data[0].countElements;
  var target = parseInt(json.data[0].target,10);
  var numElements = json.element.length;
  var id = gDOMID_BoxPrefix + (target);
  
  if (numElements == 0) {
      // no elements to view ?
      //showNodes (id);
      $(id+"_no").innerHTML = "";
      return;
  }
  
  var primaryAccession = json.data[0].primaryAccession;
  var name = json.data[0].pname;
  var pid = json.data[0].pid;    
  var where = targetElements(id, target);
  var wid = wrap(id, "\"");
  var text = "<span>";
  
  var numE = parseInt(json.data[0].maxElements,10);
  var maxE = parseInt(json.data[0].countElements,10);
  var maxP = parseInt(json.data[0].maxPage,10);
  var curP = parseInt(json.data[0].curPage,10);
  
  if (curP > maxP) curP = maxP;
  if (curP < 0) curP = 0;
  
  var nextPageTarget = (curP+1);
  var prevPageTarget = (curP-1);
  
  if (nextPageTarget > maxP) nextPageTarget = maxP;
  if (nextPageTarget < 0) nextPageTarget = 0;
  
  if (prevPageTarget > maxP) prevPageTarget = maxP;
  if (prevPageTarget < 0)  prevPageTarget = 0;
  
  var prevLink = 'javascript:getElementsViaAjax('+ (-1) +', '+ maxE +', "'+pid+'", "'+primaryAccession+'", "'+(target)+'", "", '+prevPageTarget+', false, true)';
  var nextLink = 'javascript:getElementsViaAjax('+ (-1) +', '+ maxE +', "'+pid+'", "'+primaryAccession+'", "'+(target)+'", "", '+nextPageTarget+', false, true)';
  var pageLink = "";
  
  text+="</span><ul>";
  
  var i;
  var jsonPA = json.data[0].primaryAccession;
  for (i=0; i<(numElements);i++) {
      var element = json.element[i];
      
      var el_PrimaryAccession=element.primaryAccession;
      var pname = element.organismName;
      var myid = id + "_e_" + i;
      
      if (el_PrimaryAccession == jsonPA) {
	  selectedElement = myid;                    
      }
      
      text += "<li class='sheet' id='"+ myid +"'>";
      var link = 'javascript:';
      link += 'showPath(-1, -1, "'+ pid +'", "'+ primaryAccession +'","'+ (target+1) +'","'+ name +'");';
      link += 'getDetailViaAjax('+ i +', '+ numElements +', "'+pid+'", "'+el_PrimaryAccession+'", "'+(target+1)+'", "'+name+'");';
      link += 'selectID("'+ myid +'");';
      text += makeLink(link, pname);
      text += "</li>";
  }
  text+="</ul>";
  
  if (numElements>0) {
      if (maxP > 0) {
	  pageLink +="<span class='prev'>";
	  pageLink +=makeLink(prevLink, "prev");
	  pageLink +="</span>";
	  pageLink +="("+(curP+1)+"/"+(maxP+1)+")";
	  pageLink +="<span class='next'>";
	  pageLink +=makeLink(nextLink, "next");
	  pageLink +="</span>";
	  $(where).className = "elementsNavi";
      }
      
      $(id+"_tabNavi").innerHTML = "<div id='"+id+"_elPages'>"+pageLink+"</div>";
      $(id+"_showEl").innerHTML = makeLink("javascript:showElements(\""+ id +"\")", "("+numTotalElements+")");
      $(id+"_showEl").style.display = gInline;
  }
  
  $(where).update(text);
  
  if (selectedElement != null) {     
      selectID(selectedElement);
  }
}

/**
 * Views the Cart
 */
function viewCartWithDb(json, db, dbName) {
  var text = "";  
  var elmentText = "";
  var elementNum = 0;
  
  json.cart.each (function (item, index) {
	  if (item.db == db) {
	      elementNum++;
	      var pTitle = item.pname;
	      var pid = item.pid;
	      
	      // MAKE PATH
	      if (pid == "") {
		  pid = "all";
	      }
	      var spid = pid.split(";");
	      var i;
	      var len = spid.length;
	      var newpid = "";
	      for (i=0; i<len; i++) {
		  newpid+='<span';        
		  if ((i<(len-2)) && (len>1)) {
		      newpid+=' class="arrowBlack"';
		  }
		  
		  newpid+='>';
		  newpid+=spid[i];
		  newpid+='</span> ';
	      }
	      pid = newpid;
	      /// PathREADY
	      
	      var pText = pid+(item.model=="element"?(" ["+item.primaryAccession+"]"):"")+"("+ item.dbName+":"+item.taxonomy + ")";
	      
	      var what = item.model=="element"?"Element":"Node";
	      var name = pTitle;      
	      var link = 'javascript:seekViaAjax("'+item.pid+'", "'+item.primaryAccession+'", "'+item.taxonomy+'", "'+item.taxonomyName+'", "'+item.db+'", "'+item.dbName+'", true);';      
	      elmentText+="<li class='cartItem"+what+" popup' popupDyn='Y' popupWidth='300' popupHeight='40' popupText='"+pText+"' popupTitle='"+pTitle+"'>";
	      elmentText+= makeLink(link, name);
	      elmentText+="</li>";
	  }      
      });
  
  if (elementNum > 0) {
      text += "<div class='database'>";
      var c = "javascript:createDownload('"+ db +"', '"+ dbName +"')";
      var downloadButton = '<a popuptext="Click to generate a file out of this list." popuptitle="Generate download for '+ dbName +'" class="popup" href=\'javascript:createDownload("'+db+'","'+dbName+'")\' onfocus="this.blur()"><img alt="Update list" src="typo3conf/ext/pm_tree/pi1/include/gfx/download_green.gif" /></a>';
      text += genTitle(dbName+"("+elementNum+")" + downloadButton);
      text += "<ul>";
      
      text += elmentText;
      text+="</ul>";
      text+="</div>";
  }
  return text;
}

function viewCart(json)
{
  var text = "";
      
  // which DBs do we have ?
  var obj =$("tx_pmtree_pi1_options_form");
  var options = obj["tx_pmtree_pi1[db]"].options;  
  var len=options.length;
  
  for (i=0; i<len; i++) {
      var o = options[i];
      
      text+=viewCartWithDb(json,o.value, o.text);
  }    
  $(gDOMID_Cart).innerHTML = text;
  $$(".popup").each(function(element) {
                new Tip(element, element.getAttribute("popuptext"), { title: element.getAttribute("popuptitle")});
  });

}

/**
 * shows Detail TAB in the box
 */ 
function showDetail(id) {
    $( id + "_detail").style.display = gBlock;
    $( id + "_tabs").style.display = gHidden;
    $( id + "_title").style.display = gHidden;
    $( id + "_tabNavi").style.display = gHidden;
    $( id + "_el").style.display = gHidden;
    $( id + "_no").style.display = gHidden;
}

/**
 * shows Elements TAB in the box
 */ 
function showElements(id) {
    $( id + "_el").style.display = gBlock;
    $( id + "_no").style.display = gHidden;
//  $( id + "_elPages").style.display = gBlock;
    $( id + "_tabNavi").style.display = gBlock;
    $( id + "_detail").style.display = gHidden;
    $( id + "_tabs").style.display = gBlock;
    $( id + "_title").style.display = gBlock;
    $( id + "_showEl").addClassName("openedElement");
    $( id + "_showNo").removeClassName("openedNode");
    $( id + "_showNo").addClassName("closedNode");
    $( id + "_showEl").removeClassName("closedElement");
}

/**
 * shows Nodes TAB in the box
 */ 
function showNodes(id) {
    $( id + "_el").style.display = gHidden;
    $( id + "_no").style.display = gBlock;
//  $( id + "_elPages").style.display = gHidden;
    $( id + "_tabNavi").style.display = gHidden;
    $( id + "_detail").style.display = gHidden;
    $( id + "_tabs").style.display = gBlock;
    $( id + "_title").style.display = gBlock;
    $( id + "_showNo").addClassName("openedNode");
    $( id + "_showEl").removeClassName("openedElement");
    $( id + "_showEl").addClassName("closedElement");
    $( id + "_showNo").removeClassName("closedNode");
}

/**
 * Shows all Nodes in the box
 */
function viewNodes(t) {
    var json = eval(t.responseText);
    var seek = json.data[0].seek == "true";
    
    var forceOpen = json.data[0].open === "true";
    var nodes = "";
    var subNodes  = null;
    var subElements  = null;
    subNodes = json.node; 
    subElements = json.element;
    
    json.data[0].countNodes = parseInt(json.data[0].countNodes, 10);
    
    var isRoot = false;
    if  (  json.data[0].pid == "" || !json.data[0].pid  ) {
	// its the root element
	json.data[0].pname = createRootName();
	json.data[0].pid = "";
	isRoot = true;
    }
    
    // TITLE
    var target = parseInt(json.data[0].target,10);
    var id = gDOMID_BoxPrefix + (target);  
    var title = "";
    title += "<span id='"+id+"_no_sel' ";
    title += "dataPrimaryAccession='"+ json.data[0].primaryAccession+"' ";
    title += "dataPID='"+json.data[0].pid+"' ";
    title += "dataPName='"+json.data[0].pname+"' ";
    title += "popupState='node_selected_"+json.data[0].cartState+"' ";
    title += "class='checkbox_"+json.data[0].cartState+"'>";
    title += makeLink('javascript:changeSelector("'+ id + "_no_sel" + '");', json.data[0].pname);
    title += "</span>";
    $(targetTitle(id, target)).innerHTML = title;
    var t = new Tip($(targetTitle(id, target)), {
	ajax: {
		url: ajaxRequestURL
+ "&tx_pmtree_pi1[type]=popup:nodetitle&tx_pmtree_pi1[pid]=" 
+ escape(json.data[0].pid) 
+ "&tx_pmtree_pi1[taxonomy]=" + gTaxonomy 
+ '&tx_pmtree_pi1[db]=' + gDatabase
+ "&tx_pmtree_pi1[model]=node_selected_" + json.data[0].cartState,
         	options: {method: 'get'} //, onSuccess: function() { t.options.title="blub"; }}
        }
    });
    
    // TABS
    var tabNodes = "(0)";
    var tabElements = "(0)";
    
    if (json.data[0].countNodes > 0) {
	tabNodes = makeLink('javascript:showNodes("'+id+'");', "("+json.data[0].countNodes +")");
    }
    if (json.data[0].countElements  > 0) {
	
	tabElements = makeLink
	    (
	     'javascript:getElementsViaAjax('+ (-1) +', '+ json.data[0].countElements +', "'+json.data[0].pid+'", "'+json.data[0].primaryAccession+'", "'+(json.data[0].target)+'", "", 0, false, true)',
	     "("+json.data[0].countElements +")"
	     );
    }
    
    // NODES
    nodes+="<ul id='"+ json.data[0].pname +"'>";
    
    var i=0;
    subNodes.each(function (node, index) {
	    i++;
	    var pid = node.path;
	    var primaryAccession="";
	    var myid = id + "_n_" + i;
	    nodes+="<li class='folder' id='"+ myid +"' name='"+ node.node_name +"'>";
	    var link = "javascript:";
	    link += 'selectID("'+ myid +'");';
	    link += 'getNodesViaAjax('+ i +', '+ json.data[0].countNodes +', "'+pid+'", "'+primaryAccession+'", "'+(target+1)+'", "'+node.node_name+'", false, true);';
	    
	    nodes+=makeLink(link, node.node_name);
	    nodes+="</li>";
	});
    nodes+="</ul>";
	    
    
    if (json.data[0].countNodes > 0) {
	$(targetTabsNodes(id, target)).innerHTML = tabNodes;
	$(targetTabsNodes(id, target)).style.display = gInline;
    } else {
	$(targetTabsNodes(id, target)).style.display = gHidden;
    }
	
    if (json.data[0].countElements  > 0) {
	$(targetTabsElements(id, target)).innerHTML = tabElements;
	$(targetTabsElements(id, target)).style.display = gInline;
    } else {
	$(targetTabsElements(id, target)).style.display = gHidden;
    }
       
    $(targetNodes(id, target)).innerHTML = nodes;
    
    // Navigate to last box if needed
    if (!seek) {
	setMaxContentBox(target); 
	updateBoxes();
    }
    
    // mark selected items:
    checkPathConstraints();
    
    // Check for Elements
    if (json.data[0].countNodes === 0) { // no Nodes? then open elements:
	getElementsViaAjax(-1,-1,json.data[0].pid, json.data[0].primaryAccession, target, json.data[0].pname, -1,  seek, true);
	showElements(id);
    } else {
	if (forceOpen) { // we want to open this folder
	    showNodes(id);
	}
    }
}

/**
 * tag an Element as selected 
 **/ 
function selectID(id) {
    updatePath();
    
    if ($(gSelected))
        $(gSelected).removeClassName("select");
    $(id).addClassName("select");  
    gSelected = id;  
}

/**
 * tag a Node as selected
 **/ 
function openID(id) {
    var obj = $(id);
    if (obj) obj.addClassName("open");
}

/**
 * tag a Node as not selected
 **/ 
function closeID(id) {
    var obj = $(id);
    if (obj) obj.removeClassName("open"); 
}

function targetDetail(id, target){  return gDOMID_BoxPrefix+(target)+"_detail";}
function targetNodes(id, target){  return gDOMID_BoxPrefix+(target)+"_no";}
function targetElements(id, target){  return gDOMID_BoxPrefix+(target)+"_el";}
function targetTitle(id, target){  return gDOMID_BoxPrefix+(target)+"_title";}
function targetTabs(id, target){  return gDOMID_BoxPrefix+(target)+"_tabs";}
function targetTabNavi(id, target){  return gDOMID_BoxPrefix+(target)+"_tabNavi";}
function targetBrowserBox(id, target){  return gDOMID_BoxPrefix+(target)+"_browserBox";}
function targetTabsNodes(id, target){  return gDOMID_BoxPrefix+(target)+"_showNo";}
function targetTabsElements(id, target){  return gDOMID_BoxPrefix+(target)+"_showEl";}

function createListBox(target, visible) {  
    var id = gDOMID_BoxPrefix+(target);
    
    var styleNone = "display:none";
    var styleBlock = "display:block";
    
    var text = "<div id='"+id+"' class='tx_pmtree_pi1_browserbox' style="+(visible?styleBlock:styleNone)+">";  
    text += "<div id='" + targetDetail(id, target ) + "' style='display:none' class='detail'></div>";
    
    text += "<p id='"+ targetTitle(id, target ) +"' class='title'>&nbsp;</p>";    
    
    text += "<div id='"+ targetTabs(id, target ) +"'class='tabs'>";
    text += "<span id='"+targetTabsNodes(id, target )+"' class='node' style='display:none'>(0)</span>";
    text += "<span id='"+targetTabsElements(id, target )+"' class='element' style='display:none'>(0)</span>";    
    text += "</div>"; // tabs
    
    text += "<div id='"+ targetTabNavi(id, target ) +"' class='tabsNavi' style='display:none'>&nbsp;</div>";  
    text += "<div id='" + targetBrowserBox(id, target ) +"' class='content'>";
    text += "<div id='" + targetNodes(id, target ) + "' style='display:block' class='nodes'>&nbsp;</div>";
    text += "<div id='" + targetElements(id, target ) + "' style='display:none' class='elements'>&nbsp;</div>";
    
    text += "</div>";
    text += "</div>";
  
    return text;
}

function createEmptyListBoxes(count) {
    if (gEmtpyListBoxesCreated==true) {
	return;
    }

    gEmtpyListBoxesCreated = true;
    var i;
    var first =1;
    
    $(gDOMID_Browser).innerHTML = "";
    for(i=first;i<=count;i++) {
	$(gDOMID_Browser).innerHTML += createListBox(i, i==first-1);    
	gMaxBox=i;
	showNodes(gDOMID_BoxPrefix+i);
    }
}

/**
 * Creates the Name for the RootBox 
 */ 
function createRootName() {
    return gDatabaseName;
}

function setMaxContentBox(target) {
    if (gMaxContentBox < target - gBoxCount + 1 ||
	gShowBoxOffset < target - gBoxCount + 1	) {   
	setBoxOffset(target - gBoxCount + 1);
    }
    gMaxContentBox = target+1; 
}

function checkScrollers() {
    if (gShowBoxOffset > 1) {
	$("tx_pmtree_pi1_navi_left").style.display = "block";
    } else {
	$("tx_pmtree_pi1_navi_left").style.display = "none";
    }

    if(gShowBoxOffset + gBoxCount < gMaxContentBox) {
	$("tx_pmtree_pi1_navi_right").style.display = "block";
    } else {
	$("tx_pmtree_pi1_navi_right").style.display = "none";
    }
}

function scroll(i) {
    if (i < 0) 
	showBoxLeft = false;
    else
	showBoxLeft=true;
    
    if (gShowBoxOffset + i < 1) 
	return;
    
    if (gShowBoxOffset + i + 1 > gMaxContentBox) 
	return;

    setOffset(gShowBoxOffset+=i);
}

function updateBoxes() {
    if (gShowBoxOffset<1) 
	setBoxOffset(1);

    var from = gShowBoxOffset;
    var to = from + gBoxCount;
    showBoxes(from, to);
}

function showBoxes(from, to)  {
    var i;
    
    for (i=1; i<=gMaxBox; i++) {
	var tObj = $(gDOMID_BoxPrefix + i);
	
	if( i>=from && i<to && i<gMaxContentBox ) {
	    tObj.style.display = gBlock;      
	} else {
	    tObj.style.display = gHidden;
	}
    }
    
    checkScrollers();
}

function updatePath() {
    var idbase="tx_pmtree_p1_BrowserPath_";
    var i;
    var run = true;
    var pathStart = false;
    var pathStop = false;
    var lastObj = null;
    for (i=0; true; i++) {
	var obj = $(idbase+i);
	if (!obj) break;

	obj.removeClassName("pathVisibleLast");
	obj.removeClassName("pathVisibleFirst");
	
	if( ((i+2)>gShowBoxOffset) && ((i+2)<(gShowBoxOffset+gBoxCount+1)) ) { 
	    if (!pathStart) {
		pathStart = true;
		obj.addClassName("pathVisibleFirst");
	    }
	    obj.addClassName("pathVisible");
	} else {     
	    if (pathStart && !pathStop) {          
		lastObj.addClassName("pathVisibleLast");
		pathStop = true; 
	    }
	    obj.removeClassName("pathVisible");
	}
	lastObj = obj;
    }
}

function showPath(nr,max, id, primaryAccession, target, pname) {
    var pstr = id.split(";");
    var text = "";
    var len=pstr.length;
    var link;
    var whiteStart = false;
    var classes;  
    var white;
    
    if (len>1) { 
	link = 'javascript:setOffset('+(0)+')';
	white = ((2)>gShowBoxOffset) && ((2)<(gShowBoxOffset+gBoxCount+1)); 
	if( white ) {
	    whiteStart = true;
	    classes = 'class="pathVisible arrowBlack"';
	} else {
	    classes = "class='arrowBlack'";
	}
	text+='<span '+classes+' id="tx_pmtree_p1_BrowserPath_'+(0)+'">';
	text += makeLink(link, createRootName());
    } else {
	text += '<span id="tx_pmtree_p1_BrowserPath_'+(999)+'">';
	text += '&nbsp; ';
    }
    text+="</span>";
    gCurrentPath = id;
    if (primaryAccession) {
	len++;
    }
    
    for(t=1;t<len;t++) {
	var te = null;
	if (primaryAccession && t == (len-1)) {
	    te = primaryAccession;
	} else {
	    te = pstr[t-1];
	}
	
	if (te!=="") {
	    link = 'javascript:setOffset('+(t+1)+')';
	    
	    white = ((t+2)>gShowBoxOffset) && ((t+2)<(gShowBoxOffset+gBoxCount+1)); 
	    if( white ) {
		if ((t+1)<len) {
		    classes = 'class="pathVisible arrowBlack"';
		} else {
		    classes = 'class="pathVisible"';
		}
	    } else {
		if ((t+1)<len) {
		    classes = 'class="arrowBlack"';
		} else {
		    classes = '';
		}
	    }
	    text+='<span '+classes+' id="tx_pmtree_p1_BrowserPath_'+t+'">';
	    text+=makeLink(link, te);
	    text+="</span>";
	}
    }
    
    $("tx_pmtree_pi1_path").innerHTML = text;
    updatePath();
}


/****************************************************
 *AJAX REQUESTS
 ****************************************************/
function requestViaAjax(what, url, request) {
    url+="&tx_pmtree_pi1[stamp]=" + Date.parse(new Date());
    var ajaxVar = new Ajax.Request ( url, request);
    ajaxVar.options.requestHeaders = ["Pragma","no-cache","Cache-Control","must-revalidate","If-Modified-Since",document.lastModified];
    
    return ajaxVar;
}

function getDetailViaAjax(nr,max, id, primaryAccession, target, pname, seeking) {
    clearTarget(targetDetail(gDOMID_BoxPrefix, target), "Loading detail...");
    showDetail(gDOMID_BoxPrefix+(target));
    resetStyle(gDOMID_BoxPrefix+(target), "detail");
    
    if (primaryAccession == null || primaryAccession == "undefined") {
	return;
    }
    
    var url = ajaxRequestURL;
    url += '&tx_pmtree_pi1[type]=detail';
    url += '&tx_pmtree_pi1[pid]=' + escape(id);
    url += '&tx_pmtree_pi1[nr]=' + nr;
    url += '&tx_pmtree_pi1[max]=' + max;  
    url += '&tx_pmtree_pi1[primaryAccession]=' + primaryAccession;
    url += '&tx_pmtree_pi1[target]=' + target;
    url += '&tx_pmtree_pi1[pname]=' + pname;
    url += '&tx_pmtree_pi1[db]=' + gDatabase;
    url += '&tx_pmtree_pi1[taxonomy]=' + gTaxonomy;
    url += '&tx_pmtree_pi1[seek]=' + seeking;
    var pars = '';
    var request = { 
	method: 'get', 
	parameters: pars,    
	onSuccess: function(t) {
	    viewDetail(eval(t.responseText));
	}
    };  
    showPath(nr,max, id, primaryAccession, target, pname);
    requestViaAjax("Detail", url, request);
}

function getCartChangedViaAjax(pid, primaryAccession, pname, what, operation, seeking) {
    var url = ajaxRequestURL;
    url += '&tx_pmtree_pi1[type]=cart:'+operation;
    url += '&tx_pmtree_pi1[pid]=' + escape(pid);
    url += '&tx_pmtree_pi1[db]=' + gDatabase;
    url += '&tx_pmtree_pi1[model]=' + what;
    url += '&tx_pmtree_pi1[taxonomy]=' + gTaxonomy;  
    url += '&tx_pmtree_pi1[primaryAccession]=' + primaryAccession;
    url += '&tx_pmtree_pi1[pname]=' + pname;
    url += '&tx_pmtree_pi1[seek]=' + seeking;
    var pars = '';
    var request = { 
	method: 'get', 
	parameters: pars,    
	onSuccess: function(t) {
	    seekViaAjax(gCurrentPath, gCurrentPrimaryAccession, gTaxonomy, gTaxonomyName, gDatabase, gDatabaseName, true);
	    getCartViaAjax(true);
	}
    }; 
    requestViaAjax("CartChange", url, request);
}
  
function refreshBrowser() {
    getCartViaAjax();
    seekViaAjax(gCurrentPath, gCurrentPrimaryAccession, gTaxonomy, gTaxonomyName, gDatabase, gDatabaseName, true);
}

function clearCart(db) {
    if (db) gDatabase = db;
  confirm(
	  "Warning", 
	  "Do you really want to clear the whole list?", 
	  function() { 
	      clearTarget(gDOMID_Cart, "Loading cart...");
	      var url = ajaxRequestURL;
	      url += '&tx_pmtree_pi1[type]=cart:clear';
	      url += '&tx_pmtree_pi1[db]=' + gDatabase;
          
	      if (gCurrentPath) {
		  url += '&tx_pmtree_pi1[pid]=' + escape(gCurrentPath);
		  url += '&tx_pmtree_pi1[taxonomy]=' + gTaxonomy;
		  url += '&tx_pmtree_pi1[primaryAccession]=' + gCurrentPrimaryAccession;  
	      } 

	      var pars = '';
	      var request = { 
		  method: 'get', parameters: pars,
		  onSuccess: function(t) {
		      var json =  eval(t.responseText);
		      
		      if (gCurrentPath) {
			  seekViaAjax(gCurrentPath, json.data[0].primaryAccession, gTaxonomy, gTaxonomyName, gDatabase, gDatabaseName, false);
			  getCartViaAjax(false);
		      } else {
			  location.reload();
		      }
		  }
	      }; 
	      
	      requestViaAjax("CartClear", url, request);
	      return true;        
	  },
	  null, "yes", "no");      
}

function getCartViaAjax(seeking) {
    clearTarget(gDOMID_Cart, "Loading cart...");
    var url = ajaxRequestURL;
    url += '&tx_pmtree_pi1[type]=cart:get';
    url += '&tx_pmtree_pi1[cartSort]=pname'; // also possible : pid, model, taxonomy
    url += '&tx_pmtree_pi1[seek]=' + seeking;
    var pars = '';
    var request = { 
	method: 'get', 
	parameters: pars,    
	onSuccess: function(t) {
	    viewCart(eval(t.responseText));
	}
    };
    requestViaAjax("Cart", url, request);
}

function resetStyle(id, what) {
    if (!$(id)) return;
    switch (what) {
    case "browserbox" :
	if ($(id).className == "tx_pmtree_pi1_detail") {
	    $(id).removeClassName("tx_pmtree_pi1_detail"); // remove
	    $(id).addClassName("tx_pmtree_pi1_browserbox"); // add browserbox
	}
	break;
    case "detail":  
	if ($(id).className == "tx_pmtree_pi1_browserbox") {
	    $(id).addClassName("tx_pmtree_pi1_detail"); // remove
	    $(id).removeClassName("tx_pmtree_pi1_browserbox"); // add browserbox
	}
	break;  
    }
    $(id).style.display = gBlock;
}

function clearTarget(id, text) {  
    var loadID = id+"_loadingContent";
    var htText =  '<div id="'+loadID+'" class="loading">'+text+'</div>';
    if ($(id)) $(id).innerHTML = htText;
}

function getNodesViaAjax(nr,max,id, primaryAccession, target, pname, seeking, forceOpen) {
    if (nr > 0 && max > 0) {
	target = parseInt(target, 10);
	if (nr > -1) {
	    // mark the one who has opened the folder
	    var tmp;
	    var i;
	    for (i=1;i<=max;i++) {
		tmp = gDOMID_BoxPrefix + (target-1)+"_n_"+ i;
		if (i==nr) {          
		    openID(tmp);
		} else {
		    closeID(tmp);
		}
	    }
	}   
    }
    clearTarget(targetNodes(gDOMID_BoxPrefix, target), "Loading Nodes...");
    
    resetStyle(gDOMID_BoxPrefix+(target), "browserbox");
    
    if (forceOpen) {
	showNodes(gDOMID_BoxPrefix+(target));    
    }
    
    var url = ajaxRequestURL;
    url += '&tx_pmtree_pi1[type]=node';
    url += '&tx_pmtree_pi1[pid]=' + escape(id);
    url += '&tx_pmtree_pi1[nr]=' + nr;
    url += '&tx_pmtree_pi1[db]=' + gDatabase;
    url += '&tx_pmtree_pi1[max]=' + max;
    url += '&tx_pmtree_pi1[primaryAccession]=' + primaryAccession;
    url += '&tx_pmtree_pi1[target]=' + target;
    url += '&tx_pmtree_pi1[pname]=' + pname;
    url += '&tx_pmtree_pi1[db]=' + gDatabase;
    url += '&tx_pmtree_pi1[taxonomy]=' + gTaxonomy;
    url += '&tx_pmtree_pi1[seek]=' + seeking;
    url += '&tx_pmtree_pi1[open]=' + forceOpen;
    var pars = '';
    var request = { 
	method: 'get', 
	parameters: pars,    
	onSuccess: viewNodes    
    };
    requestViaAjax("Nodes", url,request);
    
    showPath(nr,max, id, primaryAccession, target, pname);
}

function killDownloadViaAjax(id) {
    var url = ListPageURL;
    url += '&tx_pmtree_pi1[cartCmd]=gen';
    url += '&tx_pmtree_pi1[id]=' + id;  
    var pars = '';
    var request = { 
	method: 'get', 
	parameters: pars
    };
    requestViaAjax("Download", url, request);
}

function getDownloadViaAjax(db, fileFormat) {
    var url = ListPageURL;
    url += '&tx_pmtree_pi1[cartCmd]=gen';
    url += '&tx_pmtree_pi1[db]=' + db;
    url += '&tx_pmtree_pi1[fileFormat]=' + fileFormat;
    var pars = '';
    var request = { 
	method: 'get', 
	parameters: pars
    };
    requestViaAjax("Download", url, request);
}

function getElementsViaAjax(nr,max,id, primaryAccession, target, pname, page,  seeking, forceOpen) {
    clearTarget(targetElements(gDOMID_BoxPrefix, target), "Loading sequence entries...");
    resetStyle(gDOMID_BoxPrefix+(target), "browserbox");
    
    if (forceOpen)  {
	showElements(gDOMID_BoxPrefix+(target));
    }

    var url = ajaxRequestURL;
    url += '&tx_pmtree_pi1[type]=element';
    url += '&tx_pmtree_pi1[pid]=' + escape(id);
    url += '&tx_pmtree_pi1[nr]=' + nr;
    url += '&tx_pmtree_pi1[max]=' + max;
    url += '&tx_pmtree_pi1[primaryAccession]=' + primaryAccession;
    url += '&tx_pmtree_pi1[target]=' + target;
    url += '&tx_pmtree_pi1[pname]=' + pname;
    url += '&tx_pmtree_pi1[db]=' + gDatabase;
    url += '&tx_pmtree_pi1[curPage]=' + page;
    url += '&tx_pmtree_pi1[taxonomy]=' + gTaxonomy;
    url += '&tx_pmtree_pi1[seek]=' + seeking;
    url += '&tx_pmtree_pi1[open]=' + forceOpen;
    var pars = '';
    var request = { 
	method: 'get', 
	parameters: pars,    
	onSuccess: viewElements
    };
    requestViaAjax("Elements", url, request);

    showPath(nr,max, id, primaryAccession, target, pname);
}

/****************************************************
 * HELPERS
 ****************************************************/
function wrap(what, w) {
    return w+ what + w;
}

function makeLink(link, name) {
    return "<a onfocus='this.blur()' href='"+ link +"'>"+ name + "</a>";
}

function closeWindow(name) {
    win_Custom[name].destroy();
}

/**
 * views a DetailWindow for the Sequence Entry
 * primaryAccession = primaryAccession
 * windowname = title
 * db (optional) = database
 * dbname (optional) = database Name
 * */      
function viewDetailWindow(primaryAccession,taxonomy, windowname, db, dbname) {
    if (db) gDatabase = db;
    if (dbname) gDatabaseName = dbname;
  
    if (windowname) {
	var strTitle = "<div class='"+gTheme+"_content'>";
	strTitle += "<div class='tx_pmtree_pi1_fulldetails'>";
	strTitle += windowname;
	strTitle += "</div>";
	strTitle += "</div>";
	
	win_Detail = new Window("wind_"+primaryAccession, {
		className: gTheme,
		width:540, 
		height:500, 
		zIndex: 95, 
		resizable: true,
		minimizable: true,
		maximizable : false,
		title: strTitle, 
		showEffect:Effect.Appear, 
		hideEffect: Effect.Fade, 
		effectOptions : {duration: 0.2},
		draggable:true,
		wiredDrag: true,
		destroyOnClose: true
	    });
    } else {    
	win_Detail = new Window("wind_"+primaryAccession, {
		className: gTheme,
		width:526, 
		height:497, 
		zIndex: 94, 
		resizable: true,
		minimizable: true,
		maximizable : false,         
		showEffect:Effect.Appear, 
		hideEffect: Effect.Fade, 
		effectOptions : {duration: 0.2},
		draggable:true,
		wiredDrag: true,
		destroyOnClose: true
	    });
    }
    var showCentered = true;
    var showModal = false;
    
    var url = ajaxRequestURL;
    url += '&tx_pmtree_pi1[type]=fulldetail';
    url += '&tx_pmtree_pi1[pid]=' + escape(primaryAccession);
    url += '&tx_pmtree_pi1[primaryAccession]=' + primaryAccession;
    url += '&tx_pmtree_pi1[db]=' + gDatabase;
    url += '&tx_pmtree_pi1[taxonomy]=' + gTaxonomy;
    
    win_Detail.setAjaxContent(url, {method: 'get'} , showCentered, showModal);
}

/**
 * views an Info Dialog for 3 Seconds
 * text = text to be viewed while showing the window
 **/  
function info(text) { 
    Dialog.info(text, {
	    windowParameters: {
		width:250, 
		    height:100
		    }, 
		showProgress: true
		}); 
    setTimeout(function(){Dialog.closeInfo();}, 2000); 
}
