// -*- JavaScript -*-
// `navi' class definition  [1997/10/30]
//   Copyright 1997 by EPSON KOWA corporation

// *************************************
// ** Private functions
// *************************************
// 論理エラー ( entry なし )
function navi__exception_no_entry( entry ){
  alert( "Logical error! Index entry `" + entry
           + "' does not exist." );
}

// 親ノードを開く
function navi__open_node( ptr ){
  while( ptr.parent )
    ( ptr = ptr.parent ).open();
}

// 文字列から tree 型オブジェクトに変換する
function navi__convert_href( href, root ){
  var result = root.find( href );
  
  if( !result )
    this.exception_no_entry( href );
  
  return result;
}


// *************************************
// ** Methods
// *************************************
// 同期
function navi__sync( ref ){
  var this_page = this.convert_href( ref, this.root );
  
  this.main_window.navi = this;
  
  if( this_page && this_page != this.current ){
    this.current = this_page;
    this.open_node( this.current );
    this.refresh();
  }
}

// Index の表示
function navi__output( document ){
  if( this.is_first() ){
    this.first = false;
    this.main_window.location.reload();
  }else{
    this.outputer.navi = this;
    this.outputer.document = document;
    
    if( this.root.data.length ){
      this.root.open();
      this.outputer.node_begin( this.root );
      this.root.output( this.outputer, false );
      this.outputer.node_end( this.root );
    }else
      this.root.output( this.outputer, true );
  }
}

// 再表示
function navi__refresh(){
  this.navi_window.location.reload();
}

// 最初かどうか
function navi__is_first(){
  return this.first;
}

// next( 進む ) button が押されたとき
function navi__next(){
  if( this.current.next )
    this.main_window.location.pathname
      = this.now_base + this.current.next.label.first;
}

// prev( 戻る ) button が押されたとき
function navi__prev(){
  if( this.current.prev )
    this.main_window.location.pathname
      = this.now_base + this.current.prev.label.first;
}

// help button が押されたとき
function navi__help(){}

// close button が押されたとき
function navi__close( window ){
  if( window )
    window.close();
  else{
    if( this.timer )
      clearTimeout( this.timer );
    navigator.navi = null;
  }
}

// all open button が押されたとき
function navi__all_open(){
  var iter = this.root;

  while( iter ){
    if( iter.data.length )
      iter.open();
    iter = iter.next;
  }

  this.refresh();
}

// \/ button が押されたとき
function navi__nopen( ref ){
  var target = this.convert_href( ref, this.root );
  
  if( target ){
    target.open();
    this.refresh();
  }
}

// |> button が押されたとき
function navi__nclose( ref ){
  var target = this.convert_href( ref, this.root );
  
  if( target ){
    target.close();
    this.refresh();
  }
}

// 項目が押されたとき
function navi__go( ref ){
  var target = this.convert_href( ref, this.root );
  
  if( target ){
    this.main_window.hash = "";
    this.main_window.location.pathname
      = this.now_base + target.label.first;
  }
}

// Main window 監視関数
function navi__watcher(){
  if( this.old_location != this.main_window.location.pathname &&
      has_property( this.main_window, "_myname" ) ){
    this.old_location = this.main_window.location.pathname;
    this.sync( this.main_window._myname );
  }
  
  this.timer = setTimeout( "self.navi.watcher()", 500 );
}

// *************************************
// ** Constructor
// *************************************
function navi( main_window, navi_window ){
  // Properties
  this.current = null;
  this.outputer = null;
  this.root = null;
  this.config = null;
  this.main_window = main_window;
  this.navi_window = navi_window;
  this.first = true;
  this.timer = null;
  this.old_location = null;
  this.now_base = null;
  
  // Methods
  this.sync = navi__sync;
  this.output = navi__output;
  this.refresh = navi__refresh;
  this.is_first = navi__is_first;
  
  this.next = navi__next;
  this.prev = navi__prev;
  this.help = navi__help;
  this.close = navi__close;
  this.all_open = navi__all_open;
  this.nopen = navi__nopen;
  this.nclose = navi__nclose;
  this.go = navi__go;
  this.watcher = navi__watcher;
  
  this.exception_no_entry = navi__exception_no_entry;
  this.open_node = navi__open_node;
  this.convert_href = navi__convert_href;
}
