<?php
class ListHelper extends AppHelper {
    var $helpers = array('Html', 'Ajax');

    var $__option = array(
        'url' => array(),
        'key' => 'id',
        'title' => 'title',
        'children' => 'item',
        'hierarchical' => false,
        'match' => false,
        'option' => false,
        'elementOption' => false
    );

    var $__elementOption = array(
        'attributes' => array(),
        'itemAttributes' => array(),
        'linkAttributes' => array(),
        'tag' => 'ul'
    );

    function generate($list, $option = array(), $elementOption = array()) {

        $option += $this->__option;

        $elementOption +=  $this->__elementOption;

        return $this->__generate($list, $option, $elementOption);
    }

    function __generate($list, $option = array(), $elementOption = array(), $pass = array()) {

        $out = '';

        $i = 0;

        $list = Set::extract('/.', $list);

        foreach($list as $value) {

            $i++;

            if($option['option']) {
                $_option = (array) Set::extract($value, $option['option']) + $option;
            }else{
                $_option =& $option;
            }

            if($_option['elementOption']) {
                $_elementOption = Set::pushDiff((array) Set::extract($value, $_option['elementOption']), $elementOption);
            }else{
                $_elementOption = $elementOption;
            }

            $path = am($pass, Set::extract($value, $_option['key']));

            if($_option['hierarchical']) {
                $url =& $path;
            }else{
                $url = (array) Set::extract($value, $_option['key']);
            }

            if(isset($_elementOption['even']) && $i % 2 === 0) {
                if(isset($_elementOption['itemAttributes']['class'])) {
                     $_elementOption['itemAttributes']['class'] .= ' '.$_elementOption['even'];
                }else{
                     $_elementOption['itemAttributes']['class'] = $_elementOption['even'];
                }
            }elseif(isset($_elementOption['odd']) && $i % 2 !== 0) {
                if(isset($_elementOption['itemAttributes']['class'])) {
                     $_elementOption['itemAttributes']['class'] .= ' '.$_elementOption['odd'];
                }else{
                     $_elementOption['itemAttributes']['class'] = $_elementOption['odd'];
                }
            }

            if($_option['match'] !== false && (array) $_option['match'] === $url) {
                if(isset($_elementOption['itemAttributes']['class'])) {
                     $_elementOption['itemAttributes']['class'] .= ' current';
                }else{
                     $_elementOption['itemAttributes']['class'] = 'current';
                }
            }

            $obj = isset($_elementOption['linkAttributes']['update']) ? 'Ajax' : 'Html';

            $li = $this->{$obj}->link(Set::extract($value, $_option['title']), am($_option['url'], $url), $_elementOption['linkAttributes']);

            if($a = Set::extract($value, $_option['children'])) {
                $li .= $this->__generate($a, $option, $elementOption, $path);
            }

            $out .= $this->Html->tag('li', $li, $_elementOption['itemAttributes']);

        }

        return $this->Html->tag($elementOption['tag'], $out, $elementOption['attributes']);
    }
}
?>