<?php

  // Build on top of administration controller
  AngieApplication::useController('admin', GLOBALIZATION_FRAMEWORK_INJECT_INTO);

  /**
   * Roles administration controller implementation
   *
   * @package angie.frameworks.authentication
   * @subpackage controller
   */
  abstract class FwRolesAdminController extends AdminController {
    
    /**
     * Home screens delegate
     *
     * @var HomescreenController
     */
    protected $homescreen_delegate;
    
    /**
     * Construct users controller
     *
     * @param Request $parent
     * @param mixed $context
     */
    function __construct(Request $parent, $context = null) {
      parent::__construct($parent, $context);
      
      if($this->getControllerName() == 'roles_admin') {
        $this->homescreen_delegate = $this->__delegate('homescreen', HOMESCREENS_FRAMEWORK_INJECT_INTO, 'admin_role');
      } // if
    } // __construct
    
    /**
     * Selected system role instance
     *
     * @var Role
     */
    protected $active_role;
    
    /**
     * Execute before any of the controller actions
     */
    function __before() {
      parent::__before();
      
      $this->wireframe->breadcrumbs->add('system_roles_admin', lang('Roles and Permissions'), Router::assemble('admin_roles'));
      
      $role_id = $this->request->getId('role_id');
      if($role_id) {
        $this->active_role = Roles::findById($role_id);
      } // if
      
      if($this->active_role instanceof Role) {
        $this->wireframe->breadcrumbs->add("system_role_{$role_id}", $this->active_role->getName(), $this->active_role->getViewUrl());
      } else {
        $this->active_role = new Role();
      } // if
      
      $this->response->assign('active_role', $this->active_role);
      
      if($this->homescreen_delegate instanceof HomescreenController) {
      	$this->homescreen_delegate->__setProperties(array(
      		'active_object' => &$this->active_role, 
      	));
      } // if
    } // __before
    
    /**
     * Display roles administration
     */
    function index() {
      $this->wireframe->actions->add('new_role', lang('New Role'), Router::assemble('admin_roles_add'), array(
        'onclick' => new FlyoutFormCallback('role_created'), 
        'icon' => AngieApplication::getImageUrl('layout/button-add.png', ENVIRONMENT_FRAMEWORK, AngieApplication::getPreferedInterface()),        
      ));
      
      $roles = array();
      foreach(Roles::find() as $role) {
        $roles[] = $role->describe($this->logged_user, true, true);
      } // foreach
      
      $this->response->assign('roles', $roles);
    } // index
    
    /**
     * View role
     */
    function view() {
      if($this->active_role->isLoaded()) {
        $this->wireframe->actions->add('change_role_permission', lang('Change Settings'), $this->active_role->getEditUrl(), array(
          'onclick' => new FlyoutFormCallback('role_updated'), 
        ));
        
        $this->response->assign('users', $this->active_role->getUsers());
      } else {
        $this->response->notFound();
      } // if
    } // view
    
    /**
     * Add role
     */
    function add() {
      if($this->request->isAsyncCall()) {
      	$role_data = $this->request->post('role');
      	$this->response->assign('role_data', $role_data);
      	
      	if($this->request->isSubmitted()) {
      	  try {
      	    $this->active_role->setAttributes($role_data);
      	    $this->active_role->save();
      	    
						clean_quick_jump_and_quick_add_cache();
      	    
      	    $this->response->respondWithData($this->active_role, array(
      	      'as' => 'role', 
      	      'detailed' => true, 
      	    ));
      	  } catch(Exception $e) {
      	    $this->response->exception($e);
      	  } // try
      	} // if
      } else {
        $this->response->badRequest();
      } // if
    } // add
    
    /**
     * Update role
     */
    function edit() {
      if($this->request->isAsyncCall() || ($this->request->isApiCall() && $this->request->isSubmitted())) {
        if($this->active_role->isLoaded()) {
          if($this->active_role->canEdit($this->logged_user)) {
            $role_data = $this->request->post('role');
            if(!is_array($role_data)) {
              $role_data = array(
                'name' => $this->active_role->getName(),
                'permissions' => $this->active_role->getPermissions(),
              );
            } // if
            
            $protect = array();
            
            if(Roles::isLastAdministratorRole($this->active_role)) {
              $protect[] = 'has_system_access'; 
              $protect[] = 'has_admin_access'; 
            } // if
            
            $this->response->assign(array(
              'role_data' => $role_data,
              'protect_role_permissions' => $protect, 
            ));
            
            if($this->request->isSubmitted()) {
              try {
                if(!array_key_exists('permissions', $role_data)) {
                  $role_data['permissions'] = array(); // No permissions submitted? Reset the array
                } // if

                // force setting protected permission values
                if (is_foreachable($protect)) {
                  foreach ($protect as $protected_permission) {
                    if (!isset($role_data['permissions'][$protected_permission])) {
                      $role_data['permissions'][$protected_permission] = true;
                    } // if
                  } // foreach
                } // if

                $this->active_role->setAttributes($role_data);
                $this->active_role->save();
                
              	clean_quick_jump_and_quick_add_cache();
              	                
                $this->response->respondWithData($this->active_role, array(
                  'as' => 'role', 
                  'detailed' => true, 
                ));
              } catch(Exception $e) {
                $this->response->exception($e);
              } // try
            } // if
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // edit
    
    /**
     * Set specific role as default role
     */
    function set_as_default() {
      if($this->request->isSubmitted() && ($this->request->isAsyncCall() || $this->request->isApiCall())) {
        if($this->active_role->isLoaded()) {
          if($this->active_role->canEdit($this->logged_user)) {
            try {
        	    Roles::setDefault($this->active_role);
        	    $this->response->respondWithData($this->active_role, array(
        	      'as' => 'role', 
        	      'detailed' => true, 
        	    ));
        	  } catch(Exception $e) {
        	    $this->response->exception($e);
        	  } // try
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // set_as_default
    
    /**
     * Drop role
     */
    function delete() {
      if($this->request->isSubmitted() && ($this->request->isAsyncCall() || $this->request->isApiCall())) {
        if($this->active_role->isLoaded()) {
          if($this->active_role->canDelete($this->logged_user)) {
            try {
              $this->active_role->delete();
              clean_permissions_cache();
              clean_quick_jump_and_quick_add_cache();
              
              $this->response->respondWithData($this->active_role, array(
                'as' => 'role', 
                'detailed' => true, 
              ));
            } catch(Exception $e) {
              $this->response->exception($e);
            } // try
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // delete
    
    /**
     * Set permission value
     */
    function set_permission_value() {
      if($this->request->isSubmitted() && ($this->request->isAsyncCall() || $this->request->isApiCall())) {
        $permission_name = $this->request->get('permission_name');
        
        if($this->active_role->isLoaded() && $permission_name && in_array($permission_name, Roles::getPermissionNames())) {
          if($this->active_role->canEdit($this->logged_user)) {
      	    try {
      	      $this->active_role->setPermissionValue($permission_name, (boolean) $this->request->get('permission_value'));
      	      $this->active_role->save();
      	      
              clean_quick_jump_and_quick_add_cache();
      	      
        	    $this->response->respondWithData($this->active_role, array(
        	      'as' => 'role', 
        	      'detailed' => true, 
        	    ));
      	    } catch(Exception $e) {
      	      $this->response->exception($e);
      	    } // try
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // set_permission_value
    
  }