<?php
/**
 * FIT Fixture ColumnFixture
 * 
 * $Id$
 * 
 * @author Luis A. Floreani <luis.floreani@gmail.com>
 * @author gERD Schaufelberger <gerd@php-tools.net>
 * @package FIT
 * @subpackage Fixture
 * @license LGPL http://www.gnu.org/copyleft/lesser.html
 * @copyright Copyright (c) 2002-2005 Cunningham & Cunningham, Inc.
 */

/**
 * load class TypeAdapter
 */
include_once 'PHPFIT/TypeAdapter.php';

/**
 * FIT Fixture: ColumnFixture
 *
 * A ColumnFixture maps columns in the test data to fields or methods of its 
 * subclasses. SimpleExample and CalculatorExample use column fixtures.
 * 
 * @version 0.1.0
 * @package FIT
 * @subpackage Fixture
 */
class PHPFIT_Fixture_Column extends PHPFIT_Fixture {

   
/**
    * TypeAdapter
    * @var object
    */
    
protected $columnBindings;
    
   
/**
    * Excecution state
    * @var bool
    */
    
protected $hasExecuted false;
    
   
/**
    * Process a table's row
    * 
    * @param Parce rows
    */    
    
public function doRows$rows 
    {
        
$this->bind$rows->parts );
        
parent::doRows$rows->more );
    }
    
   
/**
    * Process a table's row
    * 
    * @param Parce rows
    */  
    
public function doRow$row 
    {
        
$this->hasExecuted false;
        try {
            
$this->reset();
            
parent::doRow$row );
            if( !
$this->hasExecuted ) {
                
$this->execute();
            }
        } 
        catch( 
Exception $e ) {
            
$this->exception($row->leaf(), $e);
        }
    }
    
   
/**
    * process a single cell
    *
    * Generic processing of a table cell. Well, this function 
    * just ignores cells. 
    * 
    * This method may be overwritten by a subclass (ColumnFixture)
    * 
    * @param object $cell A parse object 
    * @return void
    */
    
public function doCell$cell 
    {
        
$adapter    null;
        if( isset( 
$this->columnBindings[$cell->count] ) ) {
            
$adapter    $this->columnBindings[$cell->count];
        }
        
        try {
            
$text   $cell->text();
            
            if( 
$text === '' ) {
                
$this->checkCell$cell$adapter );
                return;
            }
            
            
// skip the rest if there is no adapter
            
if( $adapter == null ) {
                
$this->ignore$cell );
                return;
            }
            
            
// a column can be a value
            
if( $adapter->field != null ) {
                
$adapter->set$adapter->parse$text ) );
                return;
            }
            
            
// or a column can be method
            
if( $adapter->method != null ) {
                
$this->checkCell$cell$adapter );
                return;
            }
        }
        catch( 
Exception $e ) {
            
$this->exception$cell$e );
        }
    
    }

   
/**
    * check whether the value of a cell matches
    * 
    * @param Parse $cell,
    * @param TypeAdapter $a
    * @return bool true on success, false otherwise
    */
    
public function checkCell$cell$a 
    {
        if( !
$this->hasExecuted ) {
            try {
                
$this->execute();
            } 
            catch(
Exception $e) {
                
$this->exception ($cell$e);
            }
            
$this->hasExecuted true;
        }
        
        
parent::checkCell$cell$a ); 
    }
     
     
   
/**
    * bind columns of table header to functions and properties
    * 
    * @param Parse $head 
    */
    
protected function bind$heads 
    { 
        
$this->columnBindings = array( $heads->size() );
        
        for( 
$i=0$heads != null$heads $heads->more ) {
            
//echo "<br>".$heads->text();
            
$name $heads->text();
            
$suffix "()";
            try {
                if (
$name == "") {
                    
$this->columnBindings[$i] = null;
                } else if (
strstr($name$suffix) !== false) {
                    
$this->columnBindings[$i] = $this->bindMethod(substr($name0strlen($name)-strlen($suffix)));
                } else {
                    
$this->columnBindings[$i] = $this->bindField($name);
                }
            } catch (
Exception $e) {
                
$this->exception($heads$e);
            }
            
$i=$i+1;
        }
    }
    
    
    
/**
     * @param String name
     * @return TypeAdapter
     */
     
    
protected function bindMethod($name) {
        return 
PHPFIT_TypeAdapter::onMethod($this$name);
    }

    
/**
     * @param String name
     * @return TypeAdapter
     */
     
    
protected function bindField($name) {
        return 
PHPFIT_TypeAdapter::onField($this$name);
    }
    
    public function 
reset() {
    
    }
    
    public function 
execute() {
    
    }

}
?>