/*******************************************************************************
* flap-it2.js
********************************************************************************
* @file         flap-it2.js
*
* @version      flap-it $Rev: 0 $
* @copyright    Copyright (C) 2007 S+P LION AG
*
* @brief        javascripts for the SAP-PlayBooks
*               Kann direkt flap-it.js ersetzen
*
* @author       Andreas Christ <andreas.christ@sp-lion.com>
*
* @date         03.04.2007 08:27 / Andreas Christ
*                 Version 2.
*                 - expand hinzugefügt
*                 - set_static hinzugefuegt
*                 - Variable stat eingefuegt
*
*******************************************************************************/

/* Danger zone do not pass this line                                          */
/* do not change this source-code because it provides unexpected effects      */
/* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */

//==============================================================================
// CLASSES
//==============================================================================

// Klasse Navigation -----------------------------------------------------------
function Navigation( object_name )
  {
    var nav_all = new Array();
    var obj_name = object_name;         // spaeter selbst ermitteln
    var given_uid = 'flapit';           // vorgegebener praefix fuer IDste
    var p_id_list = new Array();        // Liste aller <p>-ids
    var a_id_list = new Array();        // Liste aller <a>-ids
    var ziel = '';                      // Name des Zielframes
    var debug  = 0;                     // debug > 0 => Anzeige der IDs
    var stat   = 0;                     // 1:statisches Menue -> ohne klappen
    var last_p_id = '';                 // Zuletzt aufgerufener Link

    var icons = new Array();            // pictures vor den Listeneintraegen
        icons['open']  = '';            //      offen
        icons['close'] = '';            //      geschlossen
        icons['doc']   = '';            //      Dokumenticon
        icons['blank'] = 'blank.gif';   //      leeres Icon

    var image_space = 12;               // Standardbreite eines Bildes
                                        // wird zum positionieren der Liste
                                        // verwendet.


    //------------------------------------------------------------------------
    this.debug = function( val )
    //------------------------------------------------------------------------
    // public
    // @brief   : Setzt die private Variable fuer das Frametarget
    // val      : 0->debug off, 1->debug on
    //------------------------------------------------------------------------
      {
        debug = ( val >= 0 ) ? val : 0 ;
      }  // push()


    //------------------------------------------------------------------------
    this.set_image_space = function( pixel )
    //------------------------------------------------------------------------
    // public
    // @brief   : Setzt den linken Einzug bei den Listeneintraegen.
    // pixel    :
    //------------------------------------------------------------------------
      {
        image_space = pixel;
      }  // push()


    //------------------------------------------------------------------------
    this.set_target = function( targ )
    //------------------------------------------------------------------------
    // public
    // @brief   : Setzt die private Variable fuer das Frametarget
    //------------------------------------------------------------------------
      {
        ziel = targ;
        return(0);
      }  // push()


    //------------------------------------------------------------------------
    this.set_static = function( flag )
    //------------------------------------------------------------------------
    // public
    // @brief   : Setzt die private Variable stat -> statisches Menue
    //------------------------------------------------------------------------
      {
        if( flag == 0 )
          {
            this.stat = 0;
          }  // if ...
        else
          {
            this.stat = 1;
            this.expand();
          }  // else ...
        return(0);
      }  // push()


    //------------------------------------------------------------------------
    this.push = function( arr )
    //------------------------------------------------------------------------
    // public
    // @brief   : Menue-Array hinzufuegen
    //------------------------------------------------------------------------
      {
        nav_all.push( arr );
      }  // push()


    //------------------------------------------------------------------------
    this.write = function()
    //------------------------------------------------------------------------
    // public
    // @brief   : Menue-Arrays ausgeben
    //------------------------------------------------------------------------
      {
        var idx = 0;
          for( idx=0; idx<nav_all.length; idx++ )
            {
              write_navi( nav_all[idx], idx, 1 );
            }
      }  // write()


    //------------------------------------------------------------------------
    this.set_icon = function( stat, image )
    //------------------------------------------------------------------------
    // public
    // @brief   : Setzt die icons des Menueeintrags
    // stat     : open  -> Unterpunkt geoeffnet
    //            close -> Unterpunkt geschlossen
    // image    : Bild-URL fuer offen/geschlossen
    //------------------------------------------------------------------------
      {
        var _stat = stat.toLowerCase();

          if( ( _stat == 'open' ) ||
              ( _stat == 'close' ) ||
              ( _stat == 'blank' )
            )
            {
              icons[_stat] = image;
              return( true );
            }
          else
            {
              return( false );
            }
      }  // set_icon()


    //------------------------------------------------------------------------
    function gen_img_tag( stat, uid )
    //------------------------------------------------------------------------
    // private
    // @brief   : Entfernt alle doppelten Arrayeintraege
    // stat     : Status des Eintrages ( close/open )
    //------------------------------------------------------------------------
      {
//        var $img = '<img src="';
var $img = '<img style="float: left;" src="';

          if( ( stat == 'close' ) ||
              ( stat == 'open' )
            )
            {
              $img += icons[stat];
            }
          else
            {
              $img += icons['blank'];
            }
        $img += '" alt="" id="i_' + uid + '">'
        return( $img );
      }  // gen_img_tag()


    //------------------------------------------------------------------------
    function comp_img_url( abs_url, rel_url )
    //------------------------------------------------------------------------
    // private
    // @brief   : Vergleicht eine absolute URL mit einer relativen
    // abs_url  : absolute URL
    // rel_url  : relative URL
    //------------------------------------------------------------------------
      {
        var _abs = abs_url.substr(0);
        var _rel = rel_url.substr(0);

          // fuehrende Doppelpunkte entfernen
          if( rel_url.lastIndexOf( '../' ) != -1 )
            _rel = rel_url.substr(3);
          else
            _rel = rel_url.substr(0);

          // Vergleichen rel_url in abs_url enthalten ?
          if( abs_url.lastIndexOf( _rel ) != -1 )
            return( true );
          else
            return( false );
      }  // comp_img_url()


    //------------------------------------------------------------------------
    function toggle_img( obj )
    //------------------------------------------------------------------------
    // private
    // @brief   : Wechselt das aktuelle List-Icon
    // obj      : <img>-Objekt
    //------------------------------------------------------------------------
      {
          if( comp_img_url( obj.src , icons['open'] ) )
            {
              obj.src = icons['close'];
            }
          else if( comp_img_url( obj.src , icons['close'] ) )
            {
              obj.src = icons['open'];
            }
        return( true );
      }  // toggle_img()


    //------------------------------------------------------------------------
    function dupcheck( arr )
    //------------------------------------------------------------------------
    // private
    // @brief   : Entfernt alle doppelten Arrayeintraege
    //------------------------------------------------------------------------
      {
        var unique = new Array();
        var doub = new Array().concat( arr.sort() );
        var prev = '';
        var curr = '';
          while( curr = doub.shift() )
            {
                if( curr != prev )
                  unique.push( curr );
              prev = curr;
            }
        return( unique );
      }  // gen_uid()


    //------------------------------------------------------------------------
    function gen_uid( arr )
    //------------------------------------------------------------------------
    // private
    // @brief   : Generiert eine Zeilen-uid
    //------------------------------------------------------------------------
      {
        var idx = 0;

        var uid = given_uid;
          for( idx=0; idx<arr.length; idx++ )
            {
              uid += '_' + arr[idx];
            }  // while ...
        return( uid );
      }  // gen_uid()


    //------------------------------------------------------------------------
    function str_pop( string, separate )
    //------------------------------------------------------------------------
    // private
    // @brief   : Schneidet den letzten Teilstring nach "separate" ab und
    //            liefert den Reststring zurueck
    // string   : vollstaendiger Text
    // separate : Trenner
    //------------------------------------------------------------------------
      {
        var str_split = string.split( separate );
        str_split.pop();  // letztes Element loeschen
        return( str_split.join( '_' ) );
      }  // str_pop()


    //------------------------------------------------------------------------
    function get_all_childs( arr, parent_id )
    //------------------------------------------------------------------------
    // private
    // @brief   : ermittelt alle Kindelemente der aktuellen Liste
    // arr      : Array mit allen navi-ids
    // parent_id: Id des aktuellen navi-objects
    //------------------------------------------------------------------------
      {
        // Array zur lokalen Verarbeitung sichern
        var work = new Array().concat(arr);
        var sublist = new Array();
        var item = '';
          while( item = work.shift() )
            {
              if( ( item.substr( 0, parent_id.length ) == parent_id ) && ( item != parent_id ) )
                {
                  sublist.push( item );
                }
            }
        return( sublist );
      }  // get_all_childs()


    //------------------------------------------------------------------------
    function get_childs( arr, parent_id )
    //------------------------------------------------------------------------
    // private
    // @brief   : ermittelt nur die direkten Kindselemente der aktuellen Liste
    // arr      : Array mit allen navi-ids
    // parent_id: Id des aktuellen navi-objects
    //------------------------------------------------------------------------
      {
        // Array zur lokalen Verarbeitung sichern
        var work = new Array().concat(arr);
        var sublist = new Array();
        var deep = parent_id.split( '_' ).length;  // aktuelle Verzeichnisebene
            deep++;  // naechste Verzeichnisebene
        var item = '';
          while( item = work.shift() )
            {
              if( ( item.substr( 0, parent_id.length ) == parent_id ) && ( item != parent_id ) )
                {
                  if ( item.split( '_' ).length == deep )
                    sublist.push( item );
                }
            }
        return( sublist );
      }  // get_childs()


    //------------------------------------------------------------------------
    function get_parents( arr, parent_id )
    //------------------------------------------------------------------------
    // private
    // @brief   : ermittelt die direkten Elternelemente der aktuellen Liste
    //            inklusive dem aktuellen Objekt
    // arr      : Array mit allen navi-ids
    // parent_id: Id des aktuellen navi-objects
    //------------------------------------------------------------------------
      {
        // Array zur lokalen Verarbeitung sichern
        var work = new Array().concat(arr);
        var sublist = new Array();
        var p_split = parent_id.split( '_' );
        var deep = p_split.length;  // aktuelle Verzeichnisebene
        var root = p_split[0] + '_' + p_split[1];  // oberste Ebene
        var item = '';
          while( item = work.shift() )  // Gesamtarray durchlaufen ...
            {
              if( item.substr( 0, root.length ) == root )
                {
                  if ( item.split( '_' ).length == deep )
                    sublist.push( item );
                }
            }
//        sublist.push( parent_id )
        return( sublist );
      }  // get_parents()


    //------------------------------------------------------------------------
    function get_thread( arr, parent_id )
    //------------------------------------------------------------------------
    // private
    // @brief   : ermittelt alle direkten Elternelemente der aktuellen Liste
    //            exklusive dem aktuellen Objekt
    // arr      : Array mit allen navi-ids
    // parent_id: Id des aktuellen navi-objects
    //------------------------------------------------------------------------
      {
        var thread = new Array();
            thread.push( parent_id );
        var p_split = parent_id.split( '_' );
        var deep = p_split.length;  // aktuelle Verzeichnisebene
        var idx = 0;
        var p_id = parent_id.substr(0);  // String kopieren
          for( idx=2; idx<deep; idx++ )
            {
              var p_id = str_pop( p_id, '_' )
              thread.push( p_id );
            }  // for idx ...
        return( thread );
      }  // get_thread()


    //------------------------------------------------------------------------
    function get_roots( arr )
    //------------------------------------------------------------------------
    // private
    // @brief   : ermittelt die root-IDs
    // arr      : Array mit allen navi-ids
    //------------------------------------------------------------------------
      {
        // Array zur lokalen Verarbeitung sichern
        var work = new Array().concat(arr);
        var sublist = new Array();
        var item = '';
          while( item = work.shift() )  // Gesamtarray durchlaufen ...
            {
              if( item.split( '_' ).length == 2 )
                {
                    sublist.push( item );
                }
            }
        return( sublist );
      }  // get_roots()


    //------------------------------------------------------------------------
    function get_egale( arr, parent_id )
    //------------------------------------------------------------------------
    // private
    // @brief   : ermittelt die Elemente auf gleichem SubLevel
    // arr      : Array mit allen navi-ids
    // parent_id: Id des aktuellen navi-objects
    //------------------------------------------------------------------------
      {
        // Array zur lokalen Verarbeitung sichern
        var work = new Array().concat(arr);
        var sublist = new Array();
        var p_split = parent_id.split( '_' );
          if( p_split.length == 1 )  // ungueltiger parent_id
            return( false );
        var deep = p_split.length;  // aktuelle Verzeichnisebene
        var item = '';
          while( item = work.shift() )  // Gesamtarray durchlaufen ...
            {
              // nur gleiche Levels verarbeiten
              var item_split = item.split( '_' );
                if( item_split.length == deep )
                  {
                    if( str_pop( item, '_' ) == str_pop( parent_id, '_' ) )
                      sublist.push( item );
                  }
            }
        sublist.push( parent_id );
        if( sublist.length > 0 )
          return( sublist );
        else
          return( false );
      }  // get_egale()


    //------------------------------------------------------------------------
    function write_navi( nav_arr, count, _expand  )
    //------------------------------------------------------------------------
    // private
    // @brief   : Funktion zur Ausgabe eines Arrays
    // nav_arr  : einzelnes Navigations-Array
    // count    : Arrayindex des Gesamtmenues
    // _expand  :
    //------------------------------------------------------------------------
      {
        _expand = 0;  // temporaer ueberschrieben !!!

        var navi = new Array();

        var nav_name = nav_arr.shift();
        navi.push( '<div class="flap_it_title">' + nav_name + '</div>' );

        /* ------------------ */
        var cell;
        var uid_arr = new Array();
        var last_deep = 0;
          while( cell = nav_arr.shift() )  // durchlaeuft das nav_arr
            {
              var row = cell.split( '|' );
              var deep  = parseInt( row.shift() );
              var h_ref = row.shift();
              var label = row.shift();

              // wird benoetigt zur Pruefung auf Subitems
              var next_deep = ( nav_arr[0] ) ? parseInt( nav_arr[0].substr( 0, 1 ) ) : 0;

// Anker einstellen aktiv/inaktiv
              var enable  = 'onclick="';
              var icon    = '';
                if( h_ref == '#' )
                  {
                    // Link disable -> kein Dokument hinterlegt, nur Unterliste
                    enable += obj_name + '.toggle(this);';
                    enable += 'return(false);';
                    icon = 'close';
                  }  // if h_ref ...
                else if( next_deep > deep )
                  {
                    // Link enable und toggle -> weitere Unterliste und Dokument
                    enable += obj_name + '.toggle(this);';
                    enable += obj_name + '.mark(this);';
                    enable += 'return(true);';
                    icon = 'close';
                  }  // else if h_ref ...
                else
                  {
                    // Link enable  -> nur Dokument
                    enable += obj_name + '.toggle(this);';
                    enable += obj_name + '.mark(this);';
                    enable += 'return(true);';
                  }  // else h_ref ...
              enable += '"';
// /Anker einstellen

                // Ebene hinzufuegen ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                if( deep > last_deep )
                  {
                    uid_arr.push( 0 );
                  }
                // gleiche Ebene ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                else if( deep == last_deep )
                  {
                    var count = uid_arr.pop();
                    uid_arr.push( ++count );  // Index um eins erhoehen
                  }
                // Ebene reduzieren ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                else
                  {
                    var delta = last_deep - deep;
                    while( delta-- )
                      {
                        uid_arr.pop();
                      }
                    var last_deep = uid_arr.pop();
                    uid_arr.push( ++last_deep );  // Index um eins erhoehen
                  }
              last_deep = deep;
              var uid = gen_uid( uid_arr );
              var _href   = ( h_ref != '#' ) ? ' href="' + h_ref + '"' : ' onmouseover="this.style.cursor=\'pointer\'"';
              var _target = ' target="' + ziel + '"';
              var _class  = ' class="level' + deep + '"';
              var _id     = ' id="' + uid + '"';
                  p_id_list.push( uid );
              var _a_id   = ' id="a_' + uid + '"';
                  a_id_list.push( 'a_'+uid );
              var visible = ( deep == 1 ) ? 'block' : 'none' ;
              var _style  = ' style="display:' + visible + '"';
              var para  = '<p' + _class + _id + _style + '>';
                  para +=   '<a ' + _a_id + enable + _href + _target + '>';
                  para += gen_img_tag( icon, uid );
                    if( debug )
                      label += '(' + _id + ')';
              para += '<span style="display: block; margin-left: ' + image_space + 'px;">';
              para += label;
              para += '</span>';
              para +=   '</a>';
              para += '</p>';
              navi.push( para );
            }  // while cell ...
        document.write( navi.join( "\n" ) );
      }  // write_navi()


    //------------------------------------------------------------------------
    this.mark = function( obj )
    //------------------------------------------------------------------------
    // public
    // @brief   : Funktion zum markieren einer Zeile
    //------------------------------------------------------------------------
      {
        // Zur lokalen Verarbeitung kopieren
        var work = new Array().concat( p_id_list );
        var praefix = 'sel_';

        // alle Objekte deselektieren
        var p_id;
          while( p_id = work.shift() )
            {
              var class_name = document.getElementById( p_id ).className;
                if ( class_name.substr( 0, 4 ) == praefix )
                  {
                    document.getElementById( p_id ).className = class_name.substr( praefix.length );
                  }
            }

        // zugehoeriges <p>-Objekt ermitteln
        p_obj = document.getElementById( obj.id.substr(2) );
        // Objekt selektieren
        p_obj.className = praefix + p_obj.className;
        return(true);
      }  /* mark() */


    //------------------------------------------------------------------------
    this.toggle = function( obj )
    //------------------------------------------------------------------------
    // public
    // @brief   : Funktion zum Umschalten des Stylesheets
    // obj      : <a>-object
    //------------------------------------------------------------------------
      {
        var p_id     = obj.id.substr(2);  // p-ID extrahieren, da obj ein Anker ist
        last_p_id    = p_id;              // Merken, wenn aufgerufene Seite gleich letzter Seite
        var img_obj  = document.getElementById( 'i_' + p_id );
        var bkp_img_src = img_obj.src;
        var p_obj    = document.getElementById( p_id );
        var p_active = get_childs( p_id_list, p_id );

        // Sichtbarkeit des ersten Sub-Elements ermitteln, gilt dann fuer alle
        // Elemente der Unterliste
        var visible = ( p_active[0] )
                      ? document.getElementById( p_active[0] ).style.display
                      : 'none';

        // alle zu
if( this.stat == 0 )
{
        var p_sub = new Array().concat( p_id_list );
          while( obj_name = p_sub.shift() )
            {
              document.getElementById( obj_name ).style.display = 'none';
                if( comp_img_url( document.getElementById( 'i_' + obj_name ).src , icons['open'] ) )
                  document.getElementById( 'i_' + obj_name ).src = icons['close'];
            }  // while ...
        // subliste auf

        // ermittle alle Items auf gleichem Level und den Levels darueber
        var p_visible = new Array();  // Array der sichtbaren Elemente
        var p_egale = new Array();
        var work_p_id = p_id;
          while( p_egale = get_egale( p_id_list, work_p_id ) )
            {
              p_visible = p_visible.concat( p_egale, work_p_id );
              work_p_id = str_pop( work_p_id, '_' );  // Level eins hoeher setzen
            }
        p_visible = dupcheck( p_visible );  // doppelte Eintraege loeschen
          if( visible == 'none' )
            {
              var childs = new Array();
                if( childs = get_childs( p_id_list, p_id ) )
                  p_visible = p_visible.concat( childs );
            }  // if visible ...
        // Levels sichtbar setzen
          while( id_active = p_visible.shift() )
            {
              var act_obj = document.getElementById( id_active );
              act_obj.style.display = "block";
            }  // while ...

        // erst Sublevel-Pfeile setzen ...
        var parents = new Array().concat( get_thread( p_id_list, p_id ) );
        var par_id = '';
          while( par_id = parents.shift() )
            {
              var i_obj = document.getElementById('i_' + par_id);
              // suche .. am Anfang der img-URL
                if( comp_img_url( i_obj.src, icons['close'] ) )
                  {
                    if( par_id == p_id )
                      {
                        i_obj.src = bkp_img_src;  // beloeschten Status zuruecksetzen
                        toggle_img( i_obj );      // und togglen
                      }
                    else
                      i_obj.src = icons['open'];
                  }
            }  // while parents ...
        // ... und dann den aktuellen
}
        return( true );
      }  /* toggle() */


    //------------------------------------------------------------------------
    this.show = function( p_id )
    //------------------------------------------------------------------------
    // public
    // @brief   : Baut das Menue auf und es wird nur der Eintrag mit der
    //            id=p_id angezeigt.
    //------------------------------------------------------------------------
      {
        return( true );
      }  // show()


    //------------------------------------------------------------------------
    this.toggle_id = function( p_id )
    //------------------------------------------------------------------------
    // public
    // @brief   : toggle mit uebergebener id.
    //------------------------------------------------------------------------
      {
        var obj = document.getElementById( 'a_' + p_id );
          if( p_id != last_p_id )
            {
              this.toggle( obj );
            }
        this.mark( obj );
        return( true );
      }  // show()


    //------------------------------------------------------------------------
    this.expand = function()
    //------------------------------------------------------------------------
    // public
    // @brief   : Klappt alle Unterpunkte des Menues auf.
    //------------------------------------------------------------------------
      {
        // Liste aller Objekte durchlaufen und Stylesheet wechseln
        var work = new Array().concat( p_id_list );
          while( p_id = work.shift() )
            {
              var p_obj = document.getElementById( p_id )
              p_obj.style.display = "block";
            }  // while p_id ...
        return( true );
      }  // expand()


    //------------------------------------------------------------------------
    this.collapse = function()
    //------------------------------------------------------------------------
    // public
    // @brief   : Klappt alle Unterpunkte des Menues zu.
    // STATUS -> not implemented
    //------------------------------------------------------------------------
      {
        return( true );
      }  // collapse()


    //------------------------------------------------------------------------
    this.test = function()
    //------------------------------------------------------------------------
    // public
    // @brief   : erzeugt Testlinks zur direkten Anwahl.
    //------------------------------------------------------------------------
      {
        var work = new Array().concat( p_id_list );
          while( p_id = work.shift() )
            {
              var p_obj = document.getElementById( p_id )
              document.write( "\n" );
              document.write( '<br>' );
              document.write( '<a href="#" onClick="navi.toggle_id(\''+p_id+'\');">' );
              document.write( p_id );
              document.write( '</a>' );
            }  // while p_id ...
        return( true );
      }  // test()


  }  // class Navigation()


//==============================================================================
// FUNCTIONS
//==============================================================================