<?php
/**
 * Magento
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Open Software License (OSL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/osl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@magentocommerce.com so we can send you a copy immediately.
 *
 *
 * @category    Artio
 * @package     Artio_MTurbo
 * @copyright   Copyright (c) 2013 Artio (http://www.artio.net)
 * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */

/**
 * The model
 * 
 *
 * @category    Artio
 * @package     Artio_MTurbo
 * @author      Artio Magento Team (jiri.chmiel@artio.cz)
 */
class Artio_MTurbo_Model_Layout
{

	/**
	 * Package theme.
	 * 
	 * @var string
	 */
	protected $_package = null;
	
	
	/**
	 * Skin theme.
	 * 
	 * @var string
	 */
	protected $_skin = null;
	
	
	/**
	 * List of used files.
	 * 
	 * @var array
	 */
	protected $_files = null;
	
		
	/**
	 * Set used design.
	 * 
	 * Argument $design must be something like 
	 * 'base/default', 'default/myskin1' etc.
	 * 
	 * If $design is not specified or is bad method 
	 * does nothing.
	 * 
	 * @param string $design
	 * @return Artio_MTurbo_Model_Layout
	 */
	public function setDesign($design)
	{
		$parts = explode('/', $design);
		
		// invalid $designTheme
		if (count($parts) != 2)
			return $this;
		
		$package = $parts[0];
		$skin	 = $parts[1];
		
		// invalid $designTheme
		if (!$package || !$skin)
			return $this;
		
		$this->_package = $package;
		$this->_skin	= $skin;
		
		$this->_loadLayoutFiles();
		
		return $this;
	}
	
	
	/**
	 * Get all blocks of a $filterHandle.
	 * 
	 * The result has follow formats
	 * array(
	 * 	0 => array('type' => type of block, 'name' => name in layout, 'as' => alias if anoy, 'template' => template if any ... and next attributes if any)
	 *  ...
	 * )
	 * 
	 * If xml files is not loaded or $filterHandle is not specified
	 * method returns empty array.
	 * 
	 * Note method always all blocks. Filtering by $filterHandle is done ex post.
	 * 
	 * @param string $handle
	 * @return array
	 */
	public function getBlocks($filterHandle = null)
	{
		if (!$this->_files)
			return array();
		
		$blocks = array();
		
		foreach ($this->_files as $file)
		{
			$xml = @simplexml_load_file($file);
			
			if ($xml === false)
				continue;
			
			$nodes = $xml->xpath("//block");
			
			if ($nodes) foreach ($nodes as $node)
			{
				$handle = $this->_getHandle($node);
				
				if (!$filterHandle || $handle == $filterHandle)
				{
					$info = array('handle' => $handle);
					
					foreach ($node->attributes() as $n => $v)
					{
						$info[$n] = (string) $v;
					}
					
					$blocks[] = $info;
				}
			}
		}

		return $blocks;
	}
	
	
	/**
	 * Get handle name of $node.
	 *
	 * If $node is not specified or layout hadnle not found
	 * method return false.
	 * 
	 * @param SimpleXmlElement $node
	 * @return string
	 */
	protected function _getHandle($node)
	{
		$prev = null;
		
		while ($node && $node->getName() != 'layout')
		{
			$prev = $node;
			
			$parn = $node->xpath('..');
			$node = isset($parn[0]) ? $parn[0] : false;
		}

		return $prev ? $prev->getName() : false;
	}
	

	/**
	 * Get all of used the layout files.
	 * 
	 * @param string $designTheme
	 * @return Artio_MTurbo_Model_Layout
	 */
	protected function _loadLayoutFiles()
	{
		if (!$this->_package || !$this->_skin)
			return $this;
		
		$package	= $this->_package;
		$skin		= $this->_skin;
		
		$designRoot = $this->getBaseDesignRoot();
		$helper		= $this->_funcHelper();
		
		$baseDefaultDir		= $designRoot.DS.'base'.DS.'default'.DS.'layout';
		$packageDefaultDir	= $designRoot.DS.$package.DS.'default'.DS.'layout';
		$packageSkinDir		= $designRoot.DS.$package.DS.$skin.DS.'layout';
		
		$baseDefault	= array();
		$packageDefault	= array();
		$packageSkin	= array();
		
		if (is_dir($baseDefaultDir))
			$baseDefault = $helper->list_dir($baseDefaultDir, 'f', '/\.xml$/', $rec = true);
		
		if ($package != 'base' && is_dir($packageDefaultDir))
			$packageDefault = $helper->list_dir($packageDefaultDir, 'f', '/\.xml$/', $rec = true);

		if ($skin != 'default' && is_dir($packageSkinDir))
			$packageSkin = $helper->list_dir($packageSkinDir, 'f', '/\.xml$/', $rec = true);

		if ($baseDefault === false || $packageDefault === false || $packageSkin === false)
			return false;
		
		$files = array();
		
		foreach ($packageSkin as $file)
			$files[] = $baseDefaultDir.DS.$file;
		
		foreach ($packageDefault as $file)
			if (!in_array($file, $files))
				$files[] = $packageDefaultDir.DS.$file;
		
		foreach ($baseDefault as $file)
			if (!in_array($file, $files))
				$files[] = $packageSkinDir.DS.$file;
	
		$this->_files = $files;
		
		return $this;
	}
	
	
	/**
	 * Get 'functions' helper.
	 * 
	 * @return Artio_MTurbo_Helper_Functions
	 */
	protected function _funcHelper()
	{
		return Mage::helper('mturbo/functions');
	}
	
	
	/**
	 * Method get the list of used the frontend
	 * design theme.
	 *
	 * Ex.:
	 *
	 * array(
	 * 		'base/default',
	 * 		'default/default',
	 * 		'default/iphone',
	 * 		'default/myskin1',
	 * 		'default/myskin2'
	 * )
	 *
	 * @return array
	 */
	public function getDesignsAsFlatStrings()
	{
		$designs = $this->getDesigns();
		
		$result = array();
		
		foreach ($designs as $theme => $skins)
			foreach ($skins as $skin)
				$result[] = $theme.'/'.$skin;
		
		return $result;
	}

	
	/**
	 * Method get the list of used the frontend
	 * design theme.
	 *
	 * Ex.:
	 *
	 * array(
	 * 		'base'		=> array('default')
	 * 		'default'	=> array('default', 'iphone', 'myskin1', 'myskin2')
	 * )
	 *
	 * @return array
	 */
	public function getDesigns()
	{
		$designDir = $this->getBaseDesignRoot();
	
		$packages = array();
	
		$themes = $this->_funcHelper()->list_dir($designDir, 'd');

		if ($themes === false)
			return false;
	
		foreach ($themes as $theme)
		{
			$skins = $this->_funcHelper()->list_dir($designDir.DS.$theme, 'd');
	
			if ($skins !== false)
				$packages[$theme] = $skins;
		}
	
		return $packages;
	}
	
	
	/**
	 * Get base design root.
	 *
	 * @return string
	 */
	public function getBaseDesignRoot()
	{
		return Mage::getBaseDir('app').DS.'design'.DS.'frontend';
	}
	

}