<?php
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */

/**
 * Object representation of Microsoft Excel Spreadsheets
 *
 * PHP version 5
 *
 * @category   File Formats
 * @package    Spreadsheet_Excel
 * @author     David Sanders <shangxiao@php.net>
 * @copyright  Copyright &copy; 2007, David Sanders
 * @license    LGPL <http://www.gnu.org/licenses/lgpl.html>
 * @version    Release: @release@
 * @link       http://pear.php.net/package/Spreadsheet_Excel
 * @see        Spreadsheet_Excel_Reader
 */

require_once 'Spreadsheet/Excel/Reader/Worksheet.php';

/**
 * Storage for individual data cells 
 *
 * PHP version 5
 *
 * @category   File Formats
 * @package    Spreadsheet_Excel
 * @author     David Sanders <shangxiao@php.net>
 * @copyright  Copyright &copy; 2007, David Sanders
 * @license    LGPL <http://www.gnu.org/licenses/lgpl.html>
 */

class Spreadsheet_Excel_Cell
{
    private 
$_type;

    private 
$_row_index;

    private 
$_col_index;

    private 
$_xf_index;

    
/**
     * The raw value as stored in Excel
     */
    
private $_value;

    
/**
     * Date format string conversion map
     * 
     * @access private
     * @var array
     * @todo finish?
     */
    
private $date_format_map = array(
        
'MMM' => 'x',
        
'mmm' => 'x',
        
'M'   => 'n',
        
'm'   => 'n',
        
'x'   => 'M',
        
'DD'  => 'j',
        
'dd'  => 'j',
        
'D'   => 'j',
        
'd'   => 'j',
        
'YY'  => 'y',
        
'yy'  => 'y',
        
'h'   => 'g',
        
'mm'  => 'i',
        
'ss'  => 's',
    );


    public function 
__construct(Excel_Worksheet $worksheet$row$col$xf$value$type 'LABEL')
    {
        
$this->worksheet  $worksheet;
        
$this->_row_index $row;
        
$this->_col_index $col;
        
$this->_xf_index  $xf;
        
$this->_value     $value;
        
$this->_type      $type;
    }

    public function 
getValue() 
    {
        switch (
$this->type) {

            case 
'DATE':
            return 
$this->getDate();

            case 
'NUMBER':
            case 
'LABEL':
            default:
            return 
$this->_value;
        }
    }

    
/**
     * PHP magic method.  Formats the value and returns a string.
     * 
     * @access public
     * @return string
     */
    
public function __toString()
    {
        return (string) 
$this->format();
    }

    
/**
     * Format the value.
     * 
     * a. (default) Format as specified in the spreadsheet
     * b. Format with a different format index
     * c. Format using a user-supplied format string
     * 
     * @access public
     * @return string
     */
    
public function format($format null)
    {
        if (!
is_null($format) && is_int($format)) {
            
$format_index $format;
        } else if (!
is_null($format)) {
            
// do something with the format str
        
} else {
            
$format_index $this->worksheet->workbook->xf_records[$this->_xf_index]['format_index'];
        }

        
$format_str   $this->worksheet->workbook->format_records[$format_index];

        
$type $this->getType();
        if (
$type === 'DATE') {
            return 
$this->getDateFormat($format_str);
        } else if (
$type === 'NUMBER') {
            return 
$this->getNumberFormat($format_str);
        } else {
            return 
$this->_value;
        }
    }

    
/**
     * Format the value as a date
     * 
     * @access private
     * @return string
     */
    
private function getDateFormat($format_str)
    {
        
$date $this->getDate();
        return 
$date->format(str_replace(array_keys($this->date_format_map),
                                         
array_values($this->date_format_map),
                                         
$format_str));
    }

    
/**
     * Format the value as a number format (number,percentage,money)
     * 
     * @todo handle money format
     * @access private
     * @access string
     */
    
private function getNumberFormat($format_str)
    {
        
$is_formatted strstr($format_str'#,##') !== false;
        
$matches = array();
        if (
preg_match('/0\.(0)+/'$format_str$matches)) {
            
$precision strlen($matches[1]);
        } else {
            
$precision 0;
        }

        
$is_percentage strstr($format_str'%') !== false;

        
$value $this->_value;

        if (
$is_percentage) {
            
$value *= 100;
        }

        if (
$precision 0) {
            
$value round($value$precision);
        }

        if (
$is_formatted) {
            
$value number_format($value);
        }

        if (
$is_percentage) {
            
$value .= '%';
        }

        return 
$value;
    }

    
/**
     * Create a PHP DateTime object from the value
     * 
     * @access public
     * @return DateTime
     */
    
public function getDate()
    {
        
$utc_offset $this->worksheet->workbook->datemode === Excel_Workbook::DATEMODE_MAC ?
                      
Excel_Workbook::UTCOFFSETDAYS1904 :
                      
Excel_Workbook::UTCOFFSETDAYS1900;
        
$utc_days $this->_value $utc_offset;
        
$utc_secs $utc_days Excel_Workbook::SECONDSINADAY;
        return new 
DateTime(date('r'$utc_secs));
    }

    
/**
     * Determine the type of the cell given the format
     * 
     * @access public
     * @return string type of the object - DATE, MONEY, LABEL, NUMBER
     */
    
public function getType()
    {
        
$format_index $this->worksheet->workbook->xf_records[$this->_xf_index]['format_index'];
        
$format_str   $this->worksheet->workbook->format_records[$format_index];

        
// need to improve this check
        
if ($format_index >= 14 && $format_index <= 22 ||
            
$format_index >= Excel_Workbook::BEGIN_USER_DEFINED_FORMATS && preg_match('/[dmY]/'$format_str)) {

            return 
'DATE';

        
// need to improve this check
        
} else if ($format_index >= && $format_index <= 8) {

            return 
'MONEY';

        } else if (
$format_index == 0) {

            return 
'LABEL';

        } else { 

            return 
'NUMBER';
        }

/*
        if (['type'] == 'date') {
            $this->curformat = $this->workbook->xf_records[$_xf_index]['format'];
            $this->rectype = 'date';
            return true;

        } else {
            if ($this->workbook->xf_records[$_xf_index]['type'] == 'number') {
                $this->curformat = $this->workbook->xf_records[$_xf_index]['format'];
                $this->rectype = 'number';
                if (($_xf_index == 0x9) || ($_xf_index == 0xa)){
                    $this->multiplier = 100;
                }
            }else{
                $this->curformat = Spreadsheet_Excel_Reader::DEF_NUM_FORMAT;
                $this->rectype = 'unknown';
            }
            return false;
        
        }
        */
    
}
}

/*
 * Local variables:
 * tab-width: 4
 * c-basic-offset: 4
 * c-hanging-comment-ender-p: nil
 * End:
 */
?>