<?php
 
class Agro_Acl extends Zend_Acl {
	protected static $_modules = array();
	protected static $_instance = null;
	protected static $id_user = null;
	protected static $_user = null;
	
	private function __clone() {}
	
	protected function _initialize($User) {
		
		$this->_user = $User ? $User->ds_chave : 'Guest';
		$this->id_user = $User->id;
		
		// Adiciona os modulos na ACL
		$this->initResources();
		
		// Adiciona as Roles na ACL
		$this->initRoles();
		
		// Adiciona as excecoes do usuario
		$this->initExceptions();
		
		// Seta o ADMIN com permissao total
		$this->allow('ADMIN');
	}
	
	private function initRoles($parent=false) {
		$Roles = new Sistema_Model_Roles();
		$Rs = $Roles->fetchRoles($parent);
		
		if ($Rs->count()) {
			foreach ($Rs as $Row) {
				if ($Row->parent) {
					$this->addRole(new Zend_Acl_Role($Row->role), $Row->parent);
				} else {
					$this->addRole(new Zend_Acl_Role($Row->role));
				}
				
				$this->deny($Row->role);
				$this->initPrivileges($Row->role);
				$this->initRoles($Row->id);
			}
		}
	}
	
	private function initResources() {
		$Acoes = new Sistema_Model_Acoes();
		$Rs = $Acoes->fetchResources();
		
		if ($Rs->count()) {
			foreach ($Rs as $Row) {
				$resource = Agro_Util::getResource($Row);
				
				if (!$this->has($resource)) {
					$this->add(new Zend_Acl_Resource($resource));
				}
			}
		}
	}
	
	private function initPrivileges($roleName) {
		$Roles = new Sistema_Model_RolesAcao();
		$Rs = $Roles->getPrivileges($roleName);
		
		if ($Rs && $Rs->count()) {
			foreach ($Rs as $Row) {
				$resource = Agro_Util::getResource($Row);
				
				if ($this->has($resource) && $Row->fl_permitido) {
					$this->allow($roleName, $resource);
				} else if ($this->has($resource) && !$Row->fl_permitido) {
					$this->deny($roleName, $resource);
				}
			}
		}
	}
	
	public function initExceptions() {
		$Roles = new Sistema_Model_UsuarioAcao();
		$Rs = $Roles->getPrivileges($this->id_user);
		
		if ($Rs && $Rs->count()) {
			foreach ($Rs as $Row) {
				$resource = Agro_Util::getResource($Row);
				
				if ($this->has($resource)) {
					if ($Row->fl_permitido) {
						$this->allow($this->_user, $resource);
					} else {
						$this->deny($this->_user, $resource);
					}
				}
			}
		}
	}
	
	public static function getInstance($User) {
		
		if ($User->Acl) {
			return $User->Acl;
		}
		
		if (null === self::$_instance) {
			self::$_instance = new self();
			self::$_instance->_initialize($User);
		}
		
		return self::$_instance;
	}

}