/*
The copyright of this Software (UTIPS) is assigned to Southeast Education Service Center ("SESC"), 685 E. 200 S., Price, Utah, Trustee for the Education community.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

SESC acknowledges Jay Stephens as the sage for pointing out the importance of online assessment way back in 1996.  Speaking of thinkers, here’s to the Thinkers

The misfits, the rebels, the troublemakers, the round pegs in square holes, the ones who think differently.

You can praise them, disagree with them, quote them, disbelieve them, glorify or vilify them. About the only thing you can’t do is ignore them.

Because they change things, they invent, they imagine, they heal, they explore, they create, they inspire, they push the human race forward.

They have to think differently.  How else can they stare at an empty canvas and see a work of art?  Or sit in silence and hear a song that’s never been written?  Or gaze at a red planet and see a laboratory on wheels?

We make tools for these kinds of people.  While some see them as different, we see genius.  Because the people who think differently enough to think they can change the world, are the ones who do.
*/

g_debug = 0;

function display_tree()
{
  var d = parent.frames[this.display_frame_name].document;
  var base  = parent.frames[this.code_frame_name].location.toString();
  base = base.substring(0, base.lastIndexOf("/")+1);
  
  if(this.active_node == "0")
    {
      this.active_node = this.node[this.root_key][0];
    }

  d.write("<table cellspacing=0 cellpadding=0 border=0>");
  
  this.display_node(this.node[this.root_key][0],"",0,1, base);
  
  d.write("</table>");
}

/* display individual node in tree.  recursive
 *
 * inputs:
 *   key           - this folder's key
 *   prefix        - images in front of this folder on the line
 *   is_last       - boolean, is this the last child of parent?
 *   is_root       - boolean, is this the root node?
 *
 */
function display_node(key,prefix,is_last,is_root,base)
{
  var doc             = parent.frames[this.display_frame_name].document;
  var t_have_children = (this.node[key].length > 0);
  var t_type_id       = (this.type_id[key]);
  var t_is_visible    = (this.visible[key]);
  var t_is_published  = (this.published[key] && this.published[key] != 0 && this.published[key] != '0' && this.mode != 2);
  var t_is_exported   = (this.IsExported[key] == 1);
  var t_is_imported   = (this.IsImported[key] == 1);
  
  var t_has_forum     = (this.has_forum[key]);
  var t_has_read_pass = (this.ReadPassword[key] != 0);
  var t_img_connect;
  var t_img_folder;

  if(is_last)
    { // leading L
      if(t_have_children && t_is_visible)
	{ // L-
	  t_img_connect = this.style.corner_minus;
	}
      else if(t_have_children)
	{ // L+
	  t_img_connect = this.style.corner_plus;
	}
      else
	{ // L
	  t_img_connect = this.style.corner;
	}
    }
  else
    { // leading T
      if(t_have_children && t_is_visible)
	{ // T-
	  t_img_connect = this.style.tee_minus;
	}
      else if(t_have_children)
	{ // T+
	  t_img_connect = this.style.tee_plus;
	}
      else
	{ // T
	  t_img_connect = this.style.tee;
	}
    }
  
  if(t_is_visible && t_have_children)
    {
      if(!t_is_exported && !t_is_imported)
	{
	  t_img_folder = this.style.image.opened[t_type_id];
	}
      else if(t_is_exported)
	{
	  t_img_folder = this.style.image.exported_opened[t_type_id];
	}
      else if(t_is_imported)
	{
	  t_img_folder = this.style.image.imported_opened[t_type_id];
	}
    }
  else
    {
      if(!t_is_exported && !t_is_imported)
	{
	  t_img_folder = this.style.image.closed[t_type_id];
	}
      else if(t_is_exported)
	{
	  t_img_folder = this.style.image.exported_closed[t_type_id];
	}
      else if(t_is_imported)
	{
	  t_img_folder = this.style.image.imported_closed[t_type_id];
	}
    }
  
  t_img_connect = base + t_img_connect;
  t_img_folder  = base + t_img_folder;
  
  var folder_function_str =
    "parent.frames["+'"'+this.code_frame_name+'"'+"]."+
    "controller.folder_click("+this.tree_id+","+key+");";

  var function_str_plus_minus =
    folder_function_str+
    "parent.frames["+'"'+this.code_frame_name+'"'+"]."+
    "controller.tree_click_plus_minus("+this.tree_id+","+key+");";
  
  var function_str_image_name =
    folder_function_str+
    "parent.frames["+'"'+this.code_frame_name+'"'+"]."+
    "controller.tree_click("+this.tree_id+","+key+");";
  
  doc.write("<tr><td><a onClick='"+function_str_plus_minus+"'>");
  doc.write(prefix);
  if(!is_root)
    {
      doc.write("<img src="+t_img_connect+" />");
    }
  doc.write("</a>");
  doc.write("<a onClick='"+function_str_image_name+"'>");
  doc.write("<img src="+t_img_folder+" />");
  if(t_is_published && t_has_forum)
    {
      doc.write("<img src="+base+this.style.published_forum+"  /><b>");
    }
  else if(t_is_published)
    {
      doc.write("<img src="+base+this.style.published+"  /><b>");
    }
  else if(t_has_forum)
    {
      doc.write("<img src="+base+this.style.forum+"  />");
    }
  else
    {
      doc.write("<img src="+base+this.style.empty_state+"  />");
    }
  
  if(key == this.cut_node || key == this.copy_node)
    {
      doc.write("<span class='copy_node'>" +
		this.title[key] +
		"</span>");
    }
  else if((key == this.active_node) && (this.show_active_node))
    {
      doc.write("<span class='active_node'>" +
		this.title[key] +
		"</span>");
    }
  else // normal node
    {
      doc.write("<span class='normal_node'>" +
		this.title[key] +
		"</span>");
    }
  if(t_is_published)
    {
      doc.write("</b>");
    }
  if(t_has_read_pass)
    {
      doc.write("&nbsp;<img src="+base+this.style.read_password+"  />");
   }
  doc.write("</a></td></tr>");
  
  // only display children if this node is visible
  if(t_is_visible != 1)
    { 
      return;
    }
  var t_prefix = "";
  var t_is_last;

  for(var i = 0; i < this.node[key].length; i++)
    {
      if(!is_root)
	{
	  if(is_last)
	    {
	      t_prefix = prefix +
		         "<img src=" +
		         base+this.style.empty_square +
		         " />";
	    }
	  else
	    {
	      t_prefix = prefix +
		         "<img src=" +
		         base+this.style.vertical_bar +
		         " />";
	    }
	}
      if(i < this.node[key].length - 1)
	{
	  t_is_last = 0;
	}
      else
	{
	  t_is_last = 1;
	}
      this.display_node(this.node[key][i], t_prefix, t_is_last, 0, base);
    }
}

function add_node(folder)
{
  var a;
  
  this.node[folder.parent_id].push(folder.folder_id);
  this.node[folder.folder_id] = new Array();
  
  for(a in this.attributes)
    {
      if(typeof(folder[this.attributes[a]]) != "undefined")
	{
	  this[this.attributes[a]][folder.folder_id] = folder[this.attributes[a]];
	}
    }
}

// this is the recursive function
function delete_node_aux(parent_key, node_key)
{
  // delete all children first
  while(this.node[node_key].length > 0)
    {
      this.delete_node_aux(node_key, this.node[node_key][0])
    }

  // delete self next
  var temp_array = [];
  for(var j = 0; j < this.node[parent_key].length; j++)
    {
      if(this.node[parent_key][j] != node_key)
	{
	  temp_array.push(this.node[parent_key][j]);
	}
    }
  this.node[parent_key] = temp_array;
  delete this.node[node_key];
  delete this.title[node_key];
  delete this.type_id[node_key];
  delete this.parent_id[node_key];
  delete this.published[node_key];
 
  delete this.sort_order[node_key];
  delete this.Description[node_key];
  delete this.ReadPassword[node_key];
  delete this.WritePassword[node_key];
  delete this.AnonymousUpload[node_key];
  delete this.QuickLink[node_key];
  delete this.IsExported[node_key];
  delete this.IsImported[node_key];
  delete this.SortMode[node_key];
  delete this.ViewMode[node_key];
  delete this.ReadBit[node_key];
  delete this.InsertBit[node_key];
  delete this.DeleteBit[node_key];
  delete this.ReadPasswordUser[node_key];
  delete this.WritePasswordUser[node_key];
  delete this.visible[node_key];
  delete this.is_slide[node_key];
  delete this.has_forum[node_key];
}

// this is the public non-recursive function  
function delete_node(parent_key, node_key)
{
  this.delete_node_aux(parent_key, node_key);
  this.active_node = parent_key;
}

function move_node(old_parent_key, new_parent_key, node_key)
{
  var temp_array = [];
  for(var j = 0; j < this.node[old_parent_key].length; j++)
    {
      if(this.node[old_parent_key][j] != node_key)
	{
	  temp_array.push(this.node[old_parent_key][j]);
	}
    }
  this.node[old_parent_key] = temp_array;
  this.node[new_parent_key].push(node_key);
  this.parent_id[node_key] = new_parent_key;
}

function publish_node(node_key, publish_value)
{
  this.published[node_key] = publish_value;
}


function share_node(node_key, share_value)
{
  this.IsExported[node_key] = share_value;
}

function change_title(node_key, title_value)
{
  this.title[node_key] = title_value;
}

function change_order(parent_key, node_key, predecessor_key)
{
  var temp_array = [];
  for(var j = 0; j < this.node[parent_key].length; j++)
    {
      if((j == 0 && ((predecessor_key < 0) || (predecessor_key == parent_key))))
	{
	  temp_array.push(node_key);
	}
      if(this.node[parent_key][j] != node_key)
	{
	  temp_array.push(this.node[parent_key][j]);
	}
      if(this.node[parent_key][j] == predecessor_key)
	{
	  temp_array.push(node_key);
	}
    }
  this.node[parent_key] = temp_array;
}

function update_node(folder)
{
  var a;
  for(a in this.attributes)
    {
      if(typeof(folder[this.attributes[a]]) != "undefined")
	{
	  this[this.attributes[a]][folder.folder_id] = folder[this.attributes[a]];
	}
    }
}

function reorder_tree_aux(key)
{
  var i;
  this.reorder_children(key);
  for(i = 0; i < this.node[key].length; i++)
    {
      this.reorder_tree_aux(this.node[key][i]);
    }
}

function reorder_tree()
{
  this.reorder_tree_aux(this.root_key);
}

function reorder_children(parent_key)
{
  var i;
  var j;
  var key1;
  var key2;
  
  for(i = 0; i < this.node[parent_key].length - 1; i++)
    {
      for(j = 0; j < (this.node[parent_key].length - i - 1); j++)
	{
	  key1 = this.node[parent_key][j];
	  key2 = this.node[parent_key][j+1];
	  
	  if(Number(this.sort_order[key1]) > Number(this.sort_order[key2]))
	    {
	      var temp = this.node[parent_key][j];
	      this.node[parent_key][j] = this.node[parent_key][j+1];
	      this.node[parent_key][j+1] = temp;
	    }
	}
    }
}

function slide_node(node_key, slide_value)
{
  this.is_slide[node_key] = slide_value;
}

function forum_node(node_key, forum_value)
{
  this.has_forum[node_key] = forum_value;
}

function tree_click(key)
{
  var isRoot = (this.active_node == this.node[this.root_key][0]);
  
  if(this.active_node == key)
    {
      if(this.visible[key] == 1 && !isRoot)
	{
	  this.visible[key] = 0;
	}
      else
	{
	  this.visible[key] = 1;
	}
    }
  else
    {
      this.active_node = key;
      if(this.visible[key] != 1)
	{
	  this.visible[key] = 1;
	}
    }

  if((this.parent_id[key] > 0) &&
     (this.visible[key] == 1) &&
     (this.visible[this.parent_id[key]] != 1))
    {
      this.tree_click(this.parent_id[key]);
      this.active_node = key;
    }
  
  if(g_debug > 0)
    {
      var a;
      var str = "";
      for(a in this.attributes)
	{
	  if(typeof(this[this.attributes[a]][key]) != "undefined")
	    {
	      str = str + " " + this.attributes[a] + " " + this[this.attributes[a]][key];
	    }
	}
      alert(str);
    }
}

function tree_click_plus_minus(key)
{
  this.active_node = key;
  if(this.visible[key] == 1)
    {
      this.visible[key] = 0;
    }
  else
    {
      this.visible[key] = 1;
    }
}


function t_cut_folder()
{
  this.cut_node  = this.active_node;
  this.copy_node = -1;
}

function t_copy_folder()
{
  this.copy_node = this.active_node;
  this.cut_node  = -1;
}

function t_paste_folder(c_action, c_tree_id, c_node_id, c_parent_id)
{		
	if(c_node_id == this.active_node || this.folder_is_descendent(this.active_node, c_node_id))
	{
	  alert("Can not paste into sub tree.");
	  return;
	}

	this.copy_node = -1;
	this.cut_node  = -1;

	var vars = new Object();
	vars['action']        = c_action;
	vars['user_id']       = this.user_id;
	vars['tree_id']       = this.tree_id;
	vars['old_parent_id'] = c_parent_id; // this.parent_id[c_node_id];
	vars['new_parent_id'] = this.active_node;
	vars['folder_id']     = c_node_id;
	
	vars['old_parent_item_list'] = c_parent_id;
	vars['folder_id_list'] = c_node_id;
	vars['Submit']        = 'Submit';

	this.send_action("", vars);	
}

function t_publish_folder()
{
  var vars = new Object();
  vars['action']        = "publish_folder";
  vars['user_id']       = this.user_id;
  vars['tree_id']       = this.tree_id;
  vars['folder_id']     = this.active_node;
  vars['Submit']        = 'Submit';

  this.send_action("", vars);
}


function t_send_action(action, vars)
{
  var d = parent.frames[this.load_frame_name].document;
  var i;
  var base  = parent.frames[this.code_frame_name].location.toString();
  base      = base.substring(0, base.lastIndexOf("/")+1);
  
  if(action == "")
    {
      action = "cf_folder_management.cfm";
    }
  action = base + action;
  d.open();
  d.write('<html>');
  d.write('<body>');
  d.write('<form action="'+action+'" method="post">');

  for(i in vars)
    {
      d.write('<input type="hidden" name="'+i+'" value="'+vars[i]+'">');
    }
  
  d.write('</form>');
  d.write('</body>');
  d.write('</html>');
  d.close();
  d.forms[0].submit();
}

function folder_is_descendent(folder_id, possible_parent_id)
{
  // returns true if folder_id is a descendent of possible_parent_id
  var id   = folder_id;
  var done = false;

  while(!done)
    {
      if(id == possible_parent_id)
	{
	  return true;
	}
      if(id == this.node[this.root_key][0])
	{
	  done = true;
	  continue;
	}
      id = this.parent_id[id];
    }

  return false;
}

function folder_share_root(folder_id)
{
  // returns the node_id of the folder that is the root of the share
  // folder_id is assumed to be imported or exported, otherwise the
  // results are undefined
  var id      = folder_id;
  var done    = false;
  var root_id = -1;
  var p_id    = -1;

  while(!done)
    {
      p_id = this.parent_id[id];
      if((this.IsExported[p_id] != 1) &&
	 (this.IsImported[p_id] != 1))
	{
	  root_id = id;
	  done = true;
	  break;
	}
      id = p_id;
    }

  return root_id;
}

function t_have_cut_or_copy()
{
  return ((this.cut_node != -1) || (this.copy_node != -1));
}

function t_clear_cut_and_copy()
{
  this.cut_node  = -1;
  this.copy_node = -1;
}

function t_node_is_root(node_id)
{
  return (this.parent_id[node_id] == this.root_key);
}

function t_open_root()
{
  this.visible[this.node[this.root_key][0]] = 1;
}

function t_set_root_title(title_in)
{
  this.title[this.node[this.root_key][0]] = title_in;
}

function t_get_start_page()
{
  return this.start_page;
}

function t_set_start_page(start_page_in)
{
  this.start_page = start_page_in;
}

function t_get_alpha_sort()
{
  return this.alpha_sort;
}

function t_set_alpha_sort(alpha_sort_in)
{
  this.alpha_sort = alpha_sort_in;
}

/* BEGIN read password methods */
function t_folder_read_password_required(folder_id)
{
  if(folder_id == 0 || typeof(this.ReadPassword[folder_id]) == "undefined")
    {
      return false;
    }
  if(this.ReadPassword[folder_id] != 0)
    {
      return true;
    }
  return this.folder_read_password_required(this.parent_id[folder_id]);
}

function t_get_folder_read_password_user(folder_id)
{
  if(folder_id == 0 || typeof(folder_id) == "undefined")
    {
      return "";
    }
  
  var password = this.ReadPasswordUser[folder_id];
  
  if((typeof(password) != "undefined") && (password != ""))
    {
      return password
    }

  return this.get_folder_read_password_user(this.parent_id[folder_id]);
}

function t_set_folder_read_password_user(folder_id, password)
{
  if(folder_id == 0)
    {
      return true;
    }

  this.ReadPasswordUser[folder_id] = password;
  if(this.ReadPassword[folder_id] != 0)
    {
      return true;
    }
  
  return this.set_folder_read_password_user(this.parent_id[folder_id], password);
}
/* END read password methods */

/* BEGIN write password methods */
function t_folder_write_password_required(folder_id)
{
  if(folder_id == 0)
    {
      return false;
    }
  if(this.WritePassword[folder_id] != 0)
    {
      return true;
    }
  return this.folder_write_password_required(this.parent_id[folder_id]);
}

function t_get_folder_write_password_user(folder_id)
{
  if(folder_id == 0)
    {
      return "";
    }
  
  var password = this.WritePasswordUser[folder_id];
  
  if((typeof(password) != "undefined") && (password != ""))
    {
      return password
    }

  return this.get_folder_write_password_user(this.parent_id[folder_id]);
}

function t_set_folder_write_password_user(folder_id, password)
{
  if(folder_id == 0)
    {
      return true;
    }

  this.WritePasswordUser[folder_id] = password;
  if(this.WritePassword[folder_id] != 0)
    {
      return true;
    }
  
  return this.set_folder_write_password_user(this.parent_id[folder_id], password);
}
/* END write password methods */

function t_display_debug(folder_id)
{
  var d = parent.frames[this.load_frame_name].document;
  var a;
  d.open();
  d.write("<html><body>");
  for(a in this.attributes)
    {
      d.write("attribute: "+this.attributes[a]+" value: "+this[this.attributes[a]][folder_id]+"<br>");
    }
  d.write("</body></html>");
  d.close();
}

function js_tree(code_frame_name, display_frame_name, ui_frame_name, load_frame_name, style, user_id, tree_id)
{
  /* data members */
  this.node            = new Object();
  this.node[0]	       = new Array(); // may be necessary for root
  this.title           = new Object();
  this.type_id         = new Object();
  this.parent_id       = new Object();
  this.published       = new Object();
  this.sort_order      = new Object();
  this.Description     = new Object();
  this.ReadPassword    = new Object();
  this.WritePassword   = new Object();
  this.AnonymousUpload = new Object();
  this.QuickLink       = new Object();
  this.IsExported      = new Object();
  this.IsImported      = new Object();
  this.SortMode        = new Object();
  this.ViewMode        = new Object();
  this.ReadBit         = new Object();
  this.InsertBit       = new Object();
  this.DeleteBit       = new Object();

  /* Passwords input by the user in anonymous mode */
  this.ReadPasswordUser  = new Object();
  this.WritePasswordUser = new Object();
  
  this.visible         = new Object();
  this.is_slide        = new Object();
  this.has_forum       = new Object();

  this.mode            = 0; /* 0 -- normal logged in user display
                             * 1 -- anonymous - My Page display
                             * 2 -- zip tool - static display
			     */
  
  this.attributes  = ["title", "type_id", "parent_id",
		      "published", "sort_order",
		      "Description", "ReadPassword", "WritePassword", "AnonymousUpload",
		      "QuickLink", "IsExported", "IsImported", 
		      "SortMode", "ViewMode",
		      "ReadBit", "InsertBit", "DeleteBit"];

  this.tree_id            = tree_id;
  this.code_frame_name    = code_frame_name;
  this.load_frame_name    = load_frame_name;
  this.display_frame_name = display_frame_name;
  this.ui_frame_name      = ui_frame_name;
  this.style              = style;
  this.user_id            = user_id;
  this.root_key           = "0";
  this.active_node        = "0";
  this.cut_node           = -1;
  this.copy_node          = -1;
  this.show_active_node   = 1;
  this.start_page         = "";
  this.alpha_sort         = 0;

  this.debug              = 0;

  /* methods */
  this.display_tree    = display_tree;
  this.display_node    = display_node;
  this.add_node        = add_node;
  this.delete_node     = delete_node;
  this.delete_node_aux = delete_node_aux;
  this.move_node       = move_node;
  this.publish_node    = publish_node;
  this.share_node      = share_node;
  this.change_title    = change_title;
  this.change_order    = change_order;
  this.update_node     = update_node;
  this.reorder_tree_aux= reorder_tree_aux;
  this.reorder_tree    = reorder_tree;
  this.reorder_children= reorder_children;
  this.slide_node      = slide_node;
  this.forum_node      = forum_node;
  this.tree_click      = tree_click;
  this.tree_click_plus_minus = tree_click_plus_minus;

  this.cut_folder      = t_cut_folder;
  this.copy_folder     = t_copy_folder;
  this.paste_folder    = t_paste_folder;
  this.publish_folder  = t_publish_folder;
  

  this.have_cut_or_copy   = t_have_cut_or_copy;
  this.clear_cut_and_copy = t_clear_cut_and_copy;
  this.node_is_root       = t_node_is_root;
  
  this.folder_is_descendent = folder_is_descendent;
  this.folder_share_root    = folder_share_root;
  this.send_action          = t_send_action;

  this.open_root            = t_open_root;
  this.set_root_title       = t_set_root_title;
  
  this.get_start_page       = t_get_start_page;
  this.set_start_page       = t_set_start_page;

  this.get_alpha_sort       = t_get_alpha_sort;
  this.set_alpha_sort       = t_set_alpha_sort;

  this.folder_read_password_required = t_folder_read_password_required;
  this.get_folder_read_password_user = t_get_folder_read_password_user;
  this.set_folder_read_password_user = t_set_folder_read_password_user;
  
  this.folder_write_password_required = t_folder_write_password_required;
  this.get_folder_write_password_user = t_get_folder_write_password_user;
  this.set_folder_write_password_user = t_set_folder_write_password_user;  
  this.display_debug        = t_display_debug;
}
