<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/zf2 for the canonical source repository
 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */

namespace Zend\View\Helper;

use 
Zend\I18n\Translator\Translator;
use 
Zend\I18n\Translator\TranslatorAwareInterface;
use 
Zend\View\Exception;

/**
 * Helper for setting and retrieving title element for HTML head
 */
class HeadTitle extends Placeholder\Container\AbstractStandalone implements
    
TranslatorAwareInterface
{
    
/**
     * Registry key for placeholder
     * @var string
     */
    
protected $regKey 'Zend_View_Helper_HeadTitle';

    
/**
     * Default title rendering order (i.e. order in which each title attached)
     *
     * @var string
     */
    
protected $defaultAttachOrder null;

    
/**
     * Translator (optional)
     *
     * @var Translator
     */
    
protected $translator;

    
/**
     * Translator text domain (optional)
     *
     * @var string
     */
    
protected $translatorTextDomain 'default';

    
/**
     * Whether translator should be used
     *
     * @var bool
     */
    
protected $translatorEnabled true;

    
/**
     * Retrieve placeholder for title element and optionally set state
     *
     * @param  string $title
     * @param  string $setType
     * @return \Zend\View\Helper\HeadTitle
     */
    
public function __invoke($title null$setType null)
    {
        if (
null === $setType) {
            
$setType = (null === $this->getDefaultAttachOrder())
                     ? 
Placeholder\Container\AbstractContainer::APPEND
                     
$this->getDefaultAttachOrder();
        }

        
$title = (string) $title;
        if (
$title !== '') {
            if (
$setType == Placeholder\Container\AbstractContainer::SET) {
                
$this->set($title);
            } elseif (
$setType == Placeholder\Container\AbstractContainer::PREPEND) {
                
$this->prepend($title);
            } else {
                
$this->append($title);
            }
        }

        return 
$this;
    }

    
/**
     * Set a default order to add titles
     *
     * @param string $setType
     * @return HeadTitle
     * @throws Exception\DomainException
     */
    
public function setDefaultAttachOrder($setType)
    {
        if (!
in_array($setType, array(
            
Placeholder\Container\AbstractContainer::APPEND,
            
Placeholder\Container\AbstractContainer::SET,
            
Placeholder\Container\AbstractContainer::PREPEND
        
))) {
            throw new 
Exception\DomainException(
                
"You must use a valid attach order: 'PREPEND', 'APPEND' or 'SET'"
            
);
        }
        
$this->defaultAttachOrder $setType;

        return 
$this;
    }

    
/**
     * Get the default attach order, if any.
     *
     * @return mixed
     */
    
public function getDefaultAttachOrder()
    {
        return 
$this->defaultAttachOrder;
    }

    
/**
     * Turn helper into string
     *
     * @param  string|null $indent
     * @return string
     */
    
public function toString($indent null)
    {
        
$indent = (null !== $indent)
                ? 
$this->getWhitespace($indent)
                : 
$this->getIndent();

        
$items = array();

        if (
null !== ($translator $this->getTranslator())) {
            foreach (
$this as $item) {
                
$items[] = $translator->translate(
                    
$item$this->getTranslatorTextDomain()
                );
            }
        } else {
            foreach (
$this as $item) {
                
$items[] = $item;
            }
        }

        
$separator $this->getSeparator();
        
$output '';

        
$prefix $this->getPrefix();
        if (
$prefix) {
            
$output  .= $prefix;
        }

        
$output .= implode($separator$items);

        
$postfix $this->getPostfix();
        if (
$postfix) {
            
$output .= $postfix;
        }

        
$output = ($this->autoEscape) ? $this->escape($output) : $output;

        return 
$indent '<title>' $output '</title>';
    }

    
// Translator methods - Good candidate to refactor as a trait with PHP 5.4

    /**
     * Sets translator to use in helper
     *
     * @param  Translator $translator  [optional] translator.
     *                                 Default is null, which sets no translator.
     * @param  string     $textDomain  [optional] text domain
     *                                 Default is null, which skips setTranslatorTextDomain
     * @return HeadTitle
     */
    
public function setTranslator(Translator $translator null$textDomain null)
    {
        
$this->translator $translator;
        if (
null !== $textDomain) {
            
$this->setTranslatorTextDomain($textDomain);
        }
        return 
$this;
    }

    
/**
     * Returns translator used in helper
     *
     * @return Translator|null
     */
    
public function getTranslator()
    {
        if (! 
$this->isTranslatorEnabled()) {
            return 
null;
        }

        return 
$this->translator;
    }

    
/**
     * Checks if the helper has a translator
     *
     * @return bool
     */
    
public function hasTranslator()
    {
        return (bool) 
$this->getTranslator();
    }

    
/**
     * Sets whether translator is enabled and should be used
     *
     * @param  bool $enabled [optional] whether translator should be used.
     *                       Default is true.
     * @return HeadTitle
     */
    
public function setTranslatorEnabled($enabled true)
    {
        
$this->translatorEnabled = (bool) $enabled;
        return 
$this;
    }

    
/**
     * Returns whether translator is enabled and should be used
     *
     * @return bool
     */
    
public function isTranslatorEnabled()
    {
        return 
$this->translatorEnabled;
    }

    
/**
     * Set translation text domain
     *
     * @param  string $textDomain
     * @return HeadTitle
     */
    
public function setTranslatorTextDomain($textDomain 'default')
    {
        
$this->translatorTextDomain $textDomain;
        return 
$this;
    }

    
/**
     * Return the translation text domain
     *
     * @return string
     */
    
public function getTranslatorTextDomain()
    {
        return 
$this->translatorTextDomain;
    }
}