// -*- JavaScript -*-
// `tree' class definition  [1997/11/20]
//   Copyright 1997 by EPSON KOWA corporation

// *************************************
// ** Methods
// *************************************
// ページ番号を返す
function tree__print_number( flag ){
  if( this.parent == null )
    return "";
  
  var count = 1;
  while( count - 1 < this.parent.data.length )
    if( this.parent.data[count-1] == this )
      break;
    else
      count++;
  
  if( flag )
    return this.parent.print_number( true ) + count + "-";
  else
    return this.parent.print_number( true ) + count;
}

// 表示 (outputer を通じて)
function tree__output( outputer, bullet ){
  if( this.data.length ){
    // node
    outputer.node( this, bullet );
    
    if( this.is_open() ){
      var iter = 0;
      
      outputer.node_begin( this );
      
      while( iter < this.data.length )
        this.data[iter++].output( outputer, true );
      
      outputer.node_end( this );
    }
  }else{
    // vertex
    return outputer.vertex( this, bullet );
  }
}

// 検索
function tree__find( href ){
  if( regular( this.label.first ) == regular( href ) )
    return this;
  else{
    var iter = 0;
    
    // 下位の要素を検索
    while( iter < this.data.length ){
      var result = this.data[iter++].find( href );
      
      if( result )
        return result;
    }
  }
  return null;
}

// 下位要素を表示状態にする
function tree__open(){
  this.open_flag = true;
}

// 下位要素を非表示状態にする
function tree__close(){
  this.open_flag = false;
}

// 下位要素の表示状態を返す
function tree__is_open(){
  return this.open_flag;
}

// 下位要素を追加する
function tree__add( obj ){
  this.data[this.data.length++] = obj;
  
  // 木構造
  obj.parent = this;
  
  // 双方向リンク構造
  var iter = this;
  while( iter.next )
    iter = iter.next;
  
  iter.next = obj;
  obj.prev = iter;
  
  return this;
}


// *************************************
// ** Constractor
// *************************************
function tree( label ){
  // Properties
  this.label = label;
  this.parent = null;
  this.open_flag = false;
  this.data = new Array;
  this.next = null;
  this.prev = null;
  
  // Methods
  this.print_number = tree__print_number;
  this.output = tree__output;
  this.find = tree__find;
  this.open = tree__open;
  this.close = tree__close;
  this.is_open = tree__is_open;
  this.add = tree__add;
}
