<?php
/*
Copyright 2008 Josh Heidenreich
 
This file is part of Pelzini.
 
Pelzini is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
 
Pelzini is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with Pelzini.  If not, see <http://www.gnu.org/licenses/>.
*/
 
 
/**
 * Contains the {@link VirtualEnumerationsTransformer} class
 *
 * @package Transformers
 * @author Josh
 * @since 0.3
 **/
 
/**
 * This transformer converts constants that start with the same name into an enumeration of that name.
 *
 * So if a file has the following constants:
 *   APP_VERSION
 *   ITEM_TYPE_APPLE
 *   ITEM_TYPE_ORANGE
 *
 * The APPLE and ORANGE constants will become a part of the virtual enumeration ITEM_TYPE.
 **/
class VirtualEnumerationsTransformer extends Transformer {
    public function __construct()
    {
 
    }
 
 
    /**
     * Transforms the data model before outputting.
     *
     * This transformer converts constants that start with the same name into an enumeration of that name.
     *
     * @param array $parser_model The data model to transform
     * @return array The new data model, or null if there was an error
     **/
    public function transform(&$parser_model)
    {
        foreach ($parser_model as $item) {
            if ($item instanceof ParserFile) {
                $this->processConstants ($item);
            }
        }
 
        return $parser_model;
    }
 
 
    /**
     * Processes constants for a specified file
     **/
    private function processConstants(ParserFile $file)
    {
        usort($file->constants, 'constant_name_sorter');  
        list ($last_const_id, $last_const) = each($file->constants);  
        $enum = null;
        while (list ($constant_id, $constant) = each($file->constants)) {             if ($enum) {
                // If the constant starts with the same stuff as the current enum, add it
                if (strncmp($enum->name, $constant->name, strlen($enum->name)) == 0) {                     $enum->constants[] = $constant;
                    unset ($file->constants[$constant_id]);  
                } else {
                    // It doesn't match, so do a check that the constand begins with mostly
                    // the same stuff - it can have the last two chars wrong.
                    // If it is close, the enum is shrunk to what matches
                    $num = $this->numSimilarChars($enum->name, $constant->name);
                    if ($num >= 3 and 
$num >= (strlen($enum->name) - 2)) {                         if ($constant->name[$num - 1] == '_') $num--;
                        $enum->name = substr($constant->name, 0, $num);                         $enum->constants[] = $constant;
                        unset ($file->constants[$constant_id]);  
                        // Of course if there is no match, we cannot force a match.
                    } else {
                        $enum = null;
                    }
                }
 
            } else {
                // There is no current enum, so check if one can be created by looking at the
                // last constant and the current constant
                $num = $this->numSimilarChars($last_const->name, $constant->name);
                if ($num >= 3) {
                    if ($constant->name[$num - 1] == '_') $num--;
                    $enum = $this->createVirtualEnum (substr($constant->name, 0, $num));                     $file->enumerations[] = $enum;
                    $enum->constants[] = $last_const;
                    $enum->constants[] = $constant;
                    unset ($file->constants[$last_const_id]);                     unset ($file->constants[$constant_id]);                 }
            }
 
            $last_const = $constant;
            $last_const_id = $constant_id;
        }
    }
 
 
    /**
     * Creates an enum
     **/
    private function createVirtualEnum($name)
    {
        $enum = new ParserEnumeration();
        $enum->name = $name;
        return $enum;
    }
 
 
    /**
     * Returns the number of chars in $a that are the same as the chars in $b
     **/
    private function numSimilarChars($a, $b)
    {
        $i = 0;
 
        while ($a[$i] == $b[$i]) $i++;
 
        return $i;
    }
 
 
}
 
 
function constant_name_sorter($a, $b)
{
}
 
 
?>