/*
 * <copyright>
 *  Copyright (c) 2001 by Hyperwave AG
 * </copyright>
 *
 * <file>
 *  Name:        ForCmd.js
 *  Created:     2001-01-14
 *  $Id: ForCmd.js,v 1.7 2003/07/03 08:05:58 mmair Exp $
 * </file>
 */

initPackage ( "com.hyperwave.res" );
loadClass ( "com.hyperwave.res.ResourceException" );
loadClass ( "com.hyperwave.res.ScopedMap" );

//----------------------------------------------------------------------
/**
 * Defines the behaviour of a template's for command.
 */
// <JSClass Name="com.hyperwave.res.ForCmd">

  //--------------------------------------------------------------------
  /**
   * Construct the for command node.
   * @see com.hyperwave.res.AbstractCmd
   */
  com.hyperwave.res.ForCmd = function ( aParam )
  {
    if ( aParam == "__proto__" )
      return;

    this.base$ = com.hyperwave.res.AbstractCmd;
    this.base$ ( aParam );
    delete this.base$;

    /**
     * Holds the parsed placeholder or null in case of invalid placeholder 
     */
    this.parsedPHolder_ =  
      com.hyperwave.res.Template.static_.parsePH ( this.expression_ );

    /**
     * Error flag is set when supplied placeholder is invalid
     */
    if ( this.parsedPHolder_ == null ) 
      this.error_ = new com.hyperwave.res.ResourceException (
            "com.hyperwave.res.ForCmd: Invalid placeholder '" +
            this.expression_ + "'." );
  }
  class$ = doInherit ( com.hyperwave.res.ForCmd, 
                       com.hyperwave.res.AbstractCmd );

  //--------------------------------------------------------------------
  /**
   * Parses the rest of the <code>for</code> command. This is done
   * by finding the next <code>endfor</code>.
   * @see com.hyperwave.res.AbstractCmd#doParse
   */
  class$.doParse = function ( theTemplateTail )
  {
    this.forBodyTemplate_ = 
      new com.hyperwave.res.Template 
        ( { templateString_: theTemplateTail } );
    var state = 
      this.forBodyTemplate_.continueParse ( theTemplateTail, { endfor:true, elsefor:true } );

    if ( state.error_ )
      return state;

    if ( state.parsedEndCmd_ == "elsefor" )
    {
      this.elseBodyTemplate_ =
        new com.hyperwave.res.Template 
          ( { templateString_: state.textTail_ } );
      state = 
        this.elseBodyTemplate_.continueParse ( state.textTail_, { endfor:true } );
    }

    if ( state.error_ )
      return state;

    if ( state.parsedEndCmd_ == null )
    {
      state.textTail_ = theTemplateTail;
      state.error_ = new com.hyperwave.res.ResourceException ( 
        "com.hyperwave.res.ForCmd: Could not find *endfor* statement." );
      return state;
    }

    return state;
  }

  //--------------------------------------------------------------------
  /**
   * Executes the command in the given environment. This means 
   * that the data placeholder is evaluated and iterated in this
   * case.
   * @see com.hyperwave.res.AbstractCmd#execCmd
   */
  class$.execCmd = function ( theEnv )
  {
    var ScopedMap = com.hyperwave.res.ScopedMap;
    var array = theEnv.get ( this.parsedPHolder_ );

    if ( ( array == null ) || ( array.length == 0 ) )
    {
      if ( this.elseBodyTemplate_ )
        return this.elseBodyTemplate_.fill ( theEnv );
      else
        return "";
    }

    var for_map = {};
    var for_env = new ScopedMap ( theEnv, for_map );
    var out_array = [];
    var line_ctr = 0;

    for ( var i = 0; i < array.length; ++i )
    {
      ++line_ctr;
      row_data = array [i];
      for_map.even = (line_ctr & 0x01) ? "" : "1";
      for_map.key = i;
      for_map.value = array [i];
      for_map.line = line_ctr;
      var cur_env = new ScopedMap ( for_env, row_data );    
      out_array [out_array.length] = this.forBodyTemplate_.fill ( cur_env );
    }
    
    return out_array.join ("");
  }

// </JSClass>
//----------------------------------------------------------------------

/* End of "com.hyperwave.res.ForCmd.js" */

