var expanding_elements = {}; // an associative array (hash) which will
			     // hold our klasse objects

function bind (to_object, method)
{
  return function () {to_object[method]();}
}

var ExpandingElement = function (id, // id of expanding element 
				 getOtherContent, // function that
						  // returns other
						  // state's content
				 switch_id, // the innerHTML of the
					    // switch in current state
				 other_switch_innerHTML // the
						    // innerHTML of
						    // the switch in
						    // the other state
				 )
{
  this.id = id;
  this.switch_id = switch_id;
  this.state = 'initial';
  this.storeInitialContent();
  //this.initial_content = document.getElementById(this.id).childNodes;
  this.initial = this.getInitialContent;
  this.other = getOtherContent;
  this.switch_element = document.getElementById(switch_id); // todo: dont parse on instantiation!
  this.initial_switch = this.switch_element.innerHTML;
  this.other_switch = other_switch_innerHTML

  expanding_elements[id] = this; // add to global hash
}

// returns the other state, i.e. inverts the current state
ExpandingElement.prototype.getOtherState = function ()
{
  if (this.state == 'initial')
    return 'other';
  else if (this.state == 'other')
    return 'initial';
  else
    alert("Invalid state of expanding element " + this.id + " : " + this.state);
}

ExpandingElement.prototype.storeInitialContent = function ()
{
  this.initial_content = new Array();
  childs = document.getElementById(this.id).childNodes;
  for (n in childs)
    {
      if ((childs[n].nodeType == 1) ||
	  (childs[n].nodeType == 3))
	{
	  this.initial_content.push(childs[n].cloneNode(true));
	}
    }
}

ExpandingElement.prototype.getInitialContent = function ()
{
  return this.initial_content;
}

// redraws the switch for a state given in the argument
ExpandingElement.prototype.redrawSwitch = function (tostate)
{
  this.switch_element.innerHTML = this[tostate + '_switch'];
}

ExpandingElement.prototype.toggle = function ()
{
  // redraw the switch
  this.redrawSwitch(this.getOtherState());

  // redraw the element
  this.redrawExpandingElement(this.getOtherState());

  // finally switch state
  this.state = this.getOtherState();
}

// redraw the element that is to be swapped (collapsed or expanded)
ExpandingElement.prototype.redrawExpandingElement = function (tostate)
{
  el = document.getElementById(this.id);
  //alert('# current nodes : ' + el.childNodes.length)

  // remove current child nodes
  while (el.hasChildNodes())
    {
      el.removeChild(el.firstChild);
    }
    
  // copy other nodes to element
  if (tostate == 'initial')
    {
      var other_nodes = this.initial();
      //alert('this.initial() ' + this.initial());
    }
  else
    {
      var other_nodes = this.other();
      //alert('this.other ' + this.other + '; this.other() ' + this.other());
    }
  //alert('# new nodes: ' + other_nodes.length);
  for (n in other_nodes)
    {
      //alert('other_nodes[' + n + ']: ' + other_nodes[n] + '; nodeType: ' + other_nodes[n].nodeType);
      if ((other_nodes[n].nodeType == 1) ||
	  (other_nodes[n].nodeType == 3))
	{
	  el.appendChild(other_nodes[n].cloneNode(true));
	}
    }

}
