<?php

  // Use company profile module
  AngieApplication::useController('companies', SYSTEM_MODULE);

  /**
   * User profile controller
   *
   * @package activeCollab.modules.system
   * @subpackage controllers
   */
  class UsersController extends CompaniesController {
    
    /**
     * Name of the parent module
     *
     * @var mixed
     */
    protected $active_module = SYSTEM_MODULE;
      
    /**
     * Selected use
     *
     * @var User
     */
    protected $active_user;
    
    /**
     * State controller delegate
     *
     * @var StateController
     */
    protected $state_delegate;
    
    /**
     * API client subscriptions delegate
     *
     * @var ApiClientSubscriptionsController
     */
    protected $api_client_subscriptions_delegate;
    
    /**
     * Avatar controller delegate
     *
     * @var AvatarController
     */
    protected $avatar_delegate;
    
    /**
     * Home screen delegate
     *
     * @var HomescreenController
     */
    protected $homescreen_delegate;

    /**
     * Activity logs delegate
     *
     * @var ActivityLogsController
     */
    protected $activity_logs_delegate;
    
    /**
     * Reminders delegate controller
     *
     * @var UserRemindersController
     */
    protected $reminders_delegate;
    
    /**
     * Array of controller actions that can be accessed through API
     *
     * @var array
     */
    protected $api_actions = array('view', 'add', 'edit', 'delete');
    
    /**
     * Construct users controller
     *
     * @param Request $parent
     * @param mixed $context
     */
    function __construct(Request $parent, $context = null) {
      parent::__construct($parent, $context);
      
      if($this->getControllerName() == 'users') {
        $this->state_delegate = $this->__delegate('state', ENVIRONMENT_FRAMEWORK_INJECT_INTO, 'people_company_user');
        $this->api_client_subscriptions_delegate = $this->__delegate('api_client_subscriptions', AUTHENTICATION_FRAMEWORK_INJECT_INTO, 'people_company_user');
        $this->avatar_delegate = $this->__delegate('user_avatar', AVATAR_FRAMEWORK_INJECT_INTO, 'people_company_user');
        $this->homescreen_delegate = $this->__delegate('homescreen', HOMESCREENS_FRAMEWORK_INJECT_INTO, 'people_company_user');
        $this->activity_logs_delegate = $this->__delegate('activity_logs', ACTIVITY_LOGS_FRAMEWORK_INJECT_INTO, 'people_company_user');
        $this->reminders_delegate = $this->__delegate('user_reminders', REMINDERS_FRAMEWORK_INJECT_INTO, 'people_company_user');
      } // if
    } // __construct
       
    /**
     * Prepare controller
     */
    function __before() {
      parent::__before();

      if($this->active_company->isNew()) {
        $this->response->notFound();
      } // if

      $this->wireframe->breadcrumbs->add('users', lang('Users'), $this->active_company->getUsersUrl());

      $user_id = $this->request->get('user_id');
      if($user_id) {
        $this->active_user = Users::findById($user_id);
      } // if

      if($this->active_user instanceof User) {
        $min_state = Trash::canAccess($this->logged_user) ? STATE_TRASHED : STATE_ARCHIVED;
        if(!in_array($this->active_user->getId(), $this->logged_user->visibleUserIds(null, $min_state))) {
          $this->response->notFound();
        } // if
        $this->wireframe->breadcrumbs->add('user', $this->active_user->getName(), $this->active_user->getViewUrl());

        if($this->active_user->getId() == $this->logged_user->getId()) {
          $this->wireframe->setCurrentMenuItem('profile');
        } // if
      } else {
        $this->active_user = new User();
      } // if

      $this->response->assign('active_user', $this->active_user);

      if($this->getControllerName() == 'users') {
        if($this->api_client_subscriptions_delegate instanceof ApiClientSubscriptionsController) {
          $this->api_client_subscriptions_delegate->__setProperties(array(
            'active_object' => &$this->active_user,
          ));
        } // if

        if($this->state_delegate instanceof StateController) {
          $this->state_delegate->__setProperties(array(
            'active_object' => &$this->active_user,
          ));
        } // if
  
        if($this->avatar_delegate instanceof UserAvatarController) {
          $this->avatar_delegate->__setProperties(array(
            'active_object' => &$this->active_user
          ));
        } // if
        
        if($this->homescreen_delegate instanceof HomescreenController) {
          $this->homescreen_delegate->__setProperties(array(
            'active_object' => &$this->active_user
          ));
        } // if

        if($this->activity_logs_delegate instanceof ActivityLogsController) {
          $this->activity_logs_delegate->__setProperties(array(
            'show_activities_by' => &$this->active_user
          ));
        } // if
        
        if($this->reminders_delegate instanceof UserRemindersController) {
          $this->reminders_delegate->__setProperties(array(
            'active_object' => &$this->active_user
          ));
        } // if
      } // if
    } // __before

    /**
     * Needed for user permalink
     */
    function index() {
      if($this->request->isApiCall()) {
        $this->response->respondWithData($this->active_company->getUsers(), array(
          'as' => 'users',
        ));
      } else {
        PeopleController::index();
        $this->setView(get_view_path('index', 'people', SYSTEM_MODULE));
      } // if
    } // index
    
    /**
     * Show user profile page
     */
    function view() {
      if($this->active_user->isLoaded()) {
        if($this->active_user->canView($this->logged_user)) {

          // Phone user
          if($this->request->isPhone()) {
            $this->wireframe->setPageObject($this->active_user, $this->logged_user);
            
            if($this->active_user->canEdit($this->logged_user)) {
              $this->wireframe->actions->add('edit', lang('Edit'), $this->active_user->getEditProfileUrl(), array(
                'icon' => AngieApplication::getImageUrl('layout/buttons/edit.png', SYSTEM_MODULE, AngieApplication::INTERFACE_PHONE),
                'primary' => true
              ));
            } // if

            $this->wireframe->actions->remove(array('edit_profile', 'edit_settings', 'desktop_set', 'export_vcard', 'add_to_projects', 'send_welcome_message', 'people_company_user_login_as', 'api_subscriptions', 'calendar', 'homescreen'));
            
            if($this->logged_user->is($this->active_user) || $this->logged_user->isProjectManager()) {
              $active_projects = Projects::findActiveByUser($this->active_user);
            } else {
              $active_projects = Projects::findCommonProjects($this->logged_user, $this->active_user, DB::prepare("completed_on = NULL"));
            } // if

            $this->response->assign(array(
              'active_projects' => $active_projects,
              'completed_projects_url' => Router::assemble('people_company_user_projects_archive', array('company_id' => $this->active_company->getId(), 'user_id' => $this->active_user->getId())),
              'can_view_activities' => $this->active_user->canViewActivities($this->logged_user)
            ));

          // Tablet user
          } elseif($this->request->isTablet()) {
            throw new NotImplementedError(__METHOD__);

          // Regular user
          } elseif($this->request->isWebBrowser()) {
            $this->wireframe->print->enable();

            if ($this->request->isSingleCall()) {
              if(Users::canAdd($this->logged_user, $this->active_company)) {
                $this->wireframe->actions->add('add_user', lang('New User'), $this->active_company->getAddUserUrl(), array(
                  'onclick' => new FlyoutFormCallback('user_created'),
                  'icon' => AngieApplication::getImageUrl('layout/button-add.png', ENVIRONMENT_FRAMEWORK, AngieApplication::getPreferedInterface()),
                ));
              } // if
              
              $this->wireframe->setPageObject($this->active_user, $this->logged_user);
              $this->render();
            } else {
              $this->__forward('index'); 
            } // if
            
          // print
          } else if ($this->request->isPrintCall()) {
            $this->wireframe->setPageObject($this->active_user, $this->logged_user);

            if ($this->logged_user->getId() == $this->active_user->getId() || $this->logged_user->isProjectManager()) {
              $projects = Projects::findByUser($this->logged_user, false, DB::prepare("state >= ?", array(STATE_VISIBLE)));
            } else {
              $projects = Projects::findCommonProjects($this->logged_user, $this->active_user, DB::prepare("state >= ?", array(STATE_VISIBLE)));
            } // if
            
            $this->response->assign(array(
              'activity_logs' => ActivityLogs::findRecentBy($this->logged_user, $this->active_user),
              'user_projects' => $projects
            ));
          } else {
            $this->response->respondWithData($this->active_user, array(
              'as' => 'user', 
              'detailed' => true,
            ));
          } // if
          
        } else {
          $this->response->forbidden();
        } // if
      } else {
        $this->response->notFound();
      } // if
    } // view
    
    /**
     * Create new user
     */
    function add() {
      if($this->request->isAsyncCall() || ($this->request->isApiCall() && $this->request->isSubmitted()) || $this->request->isMobileDevice()) {
        if(Users::canAdd($this->logged_user, $this->active_company)) {
          $user_data = $this->request->post('user', array(
            'role_id' => Roles::getDefault()->getId(),
            'auto_assign' => false,
          ));
          
          $this->response->assign('user_data', $user_data);
          
          if($this->request->isSubmitted(true, $this->response)) {
            try {
              DB::beginWork('Adding user @ ' . __CLASS__);
              
              // Validate password
              if($this->request->isApiCall() || array_var($user_data, 'specify_password')) {
                $errors = new ValidationErrors();

                $password = array_var($user_data, 'password');
                $password_a = array_var($user_data, 'password_a');

                if(strlen(trim($password)) < 3) {
                  $errors->addError(lang('Password has to be at least 3 letters long'), 'password');
                } else {
                  if($password != $password_a) {
                    $errors->addError(lang('Passwords Mismatch'), 'password_a');
                  } // if
                } // if

                if($errors->hasErrors()) {
                  throw $errors;
                } // if
              } else {
                $password = Authentication::getPasswordPolicy()->generatePassword();
              } // if

              $this->active_user = new User();
              $this->active_user->setAttributes($user_data);
              $this->active_user->setPassword($password);
              $this->active_user->setCompany($this->active_company);
              $this->active_user->setState(STATE_VISIBLE);

              if($this->logged_user->isPeopleManager()) {
                $this->active_user->setAutoAssignData(
                  (boolean) array_var($user_data, 'auto_assign'),
                  (integer) array_var($user_data, 'auto_assign_role_id'),
                  array_var($user_data, 'auto_assign_permissions')
                );
              } else {
                $this->active_user->setRoleId(Roles::getDefault()->getId());
              } // if

              $this->active_user->save();

              $welcome_message_sent = false;

              if(array_var($user_data, 'send_welcome_message')) {
                $welcome_message = trim(array_var($user_data, 'welcome_message'));
                if($welcome_message) {
                  ConfigOptions::setValueFor('welcome_message', $this->active_user, $welcome_message);
                } // if

                $this->logged_user->notifier()->notifyUsers($this->active_user, $this->logged_user, 'authentication/welcome', array(
                  'password' => $password,
                  'welcome_message' => $welcome_message,
                ));
              } // if

              $title = trim(array_var($user_data, 'title'));
              if($title) {
                ConfigOptions::setValueFor('title', $this->active_user, $title);
              } // if
              
              DB::commit('User added @ ' . __CLASS__);
              
              if($this->request->isPageCall()) {
                $this->response->redirectToUrl($this->active_user->getViewUrl());
              } else {
                $this->response->respondWithData($this->active_user, array(
                  'as' => 'user',
                  'detailed' => true,
                ));
              } // if
            } catch(Exception $e) {
              DB::rollback('Failed to add user @ ' . __CLASS__);
              
              AngieApplication::revertCsfrProtectionCode();

              if($this->request->isPageCall()) {
                $this->response->assign('errors', $e);
              } else {
                $this->response->exception($e);
              } // if
            } // try
          } // if
        } else {
          $this->response->forbidden();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // add
    
    /**
     * API method
     */
    function edit() {
      if($this->request->isApiCall() && $this->request->isSubmitted()) {
        if($this->active_user->isLoaded()) {
          if($this->active_user->canEdit($this->logged_user)) {
            $config_options = array('title', 'phone_work', 'phone_mobile', 'im_type', 'im_value', 'format_date', 'format_time', 'time_timezone', 'time_dst', 'time_first_week_day', 'visual_editor', 'theme', 'language');
            
            $user_data = $this->request->post('user');
            
            // Unset fields user cannot change if he is not people manager
            if(!$this->logged_user->isPeopleManager()) {
              if(isset($user_data['company_id'])) {
                unset($user_data['company_id']);
              } // if
              if(isset($user_data['role_id'])) {
                unset($user_data['role_id']);
              } // if
            } // if
            
            try {
              DB::beginWork('Updating user @ ' . __CLASS__);
              
              $this->active_user->setAttributes($user_data);
              $this->active_user->save();
              
              foreach($config_options as $config_option) {
                if($config_option == 'time_dst' || $config_option == 'visual_editor') {
                  $value = (boolean) array_var($user_data, $config_option);
                } elseif($config_option == 'time_timezone' || $config_option == 'time_first_week_day ') {
                  $value = (integer) array_var($user_data, $config_option);
                } else {
                  $value = trim(array_var($user_data, $config_option));
                } // if

                if($value === '') {
                  ConfigOptions::removeValuesFor($this->active_user, $config_option);
                } else {
                  ConfigOptions::setValueFor($config_option, $this->active_user, $value);
                } // if
              } // foreach

              DB::commit('User updated @ ' . __CLASS__);

              $this->response->respondWithData($this->active_user, array(
                'as' => 'user',
                'detailed' => true,
              ));
            } catch(Exception $e) {
              DB::rollback('Failed to update user @ ' . __CLASS__);
              $this->response->exception($e);
            } // try
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // edit
    
    /**
     * Update user profile
     */
    function edit_profile() {
      if($this->request->isApiCall() || $this->request->isAsyncCall() || $this->request->isMobileDevice()) {
        if($this->active_user->isLoaded()) {
          if($this->active_user->canEdit($this->logged_user)) {
            $config_options = array('title', 'phone_work', 'phone_mobile', 'im_type', 'im_value');
      
            $user_data = $this->request->post('user', array_merge(array(
              'first_name' => $this->active_user->getFirstName(),
              'last_name'  => $this->active_user->getLastName(),
              'email'      => $this->active_user->getEmail(),
            ), ConfigOptions::getValueFor($config_options, $this->active_user)));
            
            $this->response->assign('user_data', $user_data);
      
            if($this->request->isSubmitted(true, $this->response)) {
              try {
                DB::beginWork('Updating user profile @ ' . __CLASS__);

                $user_data['role_id'] = $this->active_user->getRoleId(); // role cannot be changed

                // people who cannot change admin's password also cannot change their e-mail
                if (!$this->active_user->canChangePassword($this->logged_user)) {
                  $user_data['email'] = $this->active_user->getEmail();
                } // if

                $this->active_user->setAttributes($user_data);

                $this->active_user->save();

                foreach($config_options as $config_option) {
                  $value = trim(array_var($user_data, $config_option));

                  if($value === '') {
                    ConfigOptions::removeValuesFor($this->active_user, $config_option);
                  } else {
                    ConfigOptions::setValueFor($config_option, $this->active_user, $value);
                  } // if
                } // foreach
                
                DB::commit('User profile updated @ ' . __CLASS__);
                
                if($this->request->isPageCall()) {
                  $this->response->redirectToUrl($this->active_user->getViewUrl());
                } else {
                  $this->response->respondWithData($this->active_user, array(
                    'as' => 'user',
                    'detailed' => true,
                  ));
                } // if
              } catch(Exception $e) {
                DB::rollback('Failed to update user profile @ ' . __CLASS__);
                
                AngieApplication::revertCsfrProtectionCode();

                if($this->request->isPageCall()) {
                  $this->response->assign('errors', $e);
                } else {
                  $this->response->exception($e);
                } // if
              } // try
            } // if
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // edit_profile
    
    /**
     * Show and process edit settings page
     */
    function edit_settings() {
      if($this->request->isApiCall() || $this->request->isAsyncCall()) {
        if($this->active_user->isLoaded()) {
          if($this->active_user->canEdit($this->logged_user)) {
            $config_options = array('format_date', 'format_time', 'time_timezone', 'time_dst', 'time_first_week_day', 'visual_editor', 'theme', 'language');
            
            $user_data = $this->request->post('user');
            if(!is_array($user_data)) {
              $user_data = array_merge(array(
                'auto_assign' => $this->active_user->getAutoAssign(),
                'auto_assign_role_id' => $this->active_user->getAutoAssignRoleId(),
                'auto_assign_permissions' => $this->active_user->getAutoAssignPermissions(),
              ), ConfigOptions::getValueFor($config_options, $this->active_user));
              
              if(!ConfigOptions::hasValueFor('language', $this->active_user)) {
                $user_data['language'] = null; 
              } // if

              if(!ConfigOptions::hasValueFor('time_dst', $this->active_user)) {
                $user_data['time_dst'] = null;
              } // if

              if(!ConfigOptions::hasValueFor('format_date', $this->active_user)) {
                $user_data['format_date'] = null;
              } // if

              if(!ConfigOptions::hasValueFor('format_time', $this->active_user)) {
                $user_data['format_time'] = null;
              } // if

              /*
              if(!ConfigOptions::hasValueFor('theme', $this->active_user)) {
                $user_data['theme'] = null;
              } // if
              */
            } // if
            
            $this->response->assign(array(
              'user_data' => $user_data,
              'default_dst_value' => (boolean) ConfigOptions::getValue('time_dst'),
            ));
      
            if($this->request->isSubmitted(true, $this->response)) {
              try {
                DB::beginWork('Updating user settings @ ' . __CLASS__);
                
              	$original_language = ConfigOptions::getValueFor('language', $this->active_user);

                $user_data['role_id'] = $this->active_user->getRoleId(); // role cannot be changed

                $this->active_user->setAttributes($user_data);

                if($this->active_user->canChangeRole($this->logged_user)) {
                  $this->active_user->setAutoAssignData(
                    (boolean) array_var($user_data, 'auto_assign'),
                    (integer) array_var($user_data, 'auto_assign_role_id'),
                    array_var($user_data, 'auto_assign_permissions')
                  );
                } // if

                $this->active_user->save();

                foreach($config_options as $config_option) {
                  // until 3.2 skip saving theme option since it will break the system apart
                  if ($config_option == 'theme') {
                    continue;
                  } // if

                  if($config_option == 'time_dst') {
                    $value = array_var($user_data, $config_option) === '' ? '' : (boolean) array_var($user_data, $config_option);
                  } elseif($config_option == 'visual_editor') {
                    $value = (boolean) array_var($user_data, $config_option);
                  } elseif($config_option == 'time_timezone' || $config_option == 'time_first_week_day') {
                    $value = (integer) array_var($user_data, $config_option);
                  } else {
                    $value = trim(array_var($user_data, $config_option));
                  } // if


                  if($value === '' && $config_option != 'theme') {
                    ConfigOptions::removeValuesFor($this->active_user, $config_option);
                  } else {
                    ConfigOptions::setValueFor($config_option, $this->active_user, $value);
                  } // if
                } // foreach
                
                if (array_var($user_data, 'language') != $original_language) {
              		clean_quick_jump_and_quick_add_cache($this->active_user);
                } // if

                DB::commit('User settings updated @ ' . __CLASS__);
                
                $this->active_user->getLanguageId(false); // Force cached language ID refresh before describe() call

                $this->response->respondWithData($this->active_user, array(
                  'as' => 'user',
                  'detailed' => true,
                ));
              } catch(Exception $e) {
                AngieApplication::revertCsfrProtectionCode();
                
                $this->response->exception($e);
              } // try
            } // if
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // edit_settings
    
    /**
     * Update user's company and role information
     */
    function edit_company_and_role() {
      if($this->request->isAsyncCall() || $this->request->isMobileDevice()) {
        if($this->active_user->isLoaded()) {
          if($this->active_user->canChangeRole($this->logged_user)) {
            $user_data = $this->request->post('user', array(
              'company_id' => $this->active_user->getCompanyId(),
              'role_id' => $this->active_user->getRoleId(),
            ));

            $exclude_company_ids = DB::executeFirstColumn('SELECT id FROM '.TABLE_PREFIX.'companies WHERE state != ? AND id != ?', STATE_VISIBLE, $this->active_user->getCompanyId());

            $this->response->assign(array(
              'user_data' => $user_data,
              'exclude_ids' => $exclude_company_ids
            ));
            
            if($this->request->isSubmitted(true, $this->response)) {
              try {
                if(isset($user_data['role_id']) && Roles::isLastAdministrator($this->active_user)) {
                  unset($user_data['role_id']);
                } // if
                
                $original_role_id = $this->active_user->getRoleId();
                
                $this->active_user->setAttributes($user_data);
                $this->active_user->save();
                
                if ($this->active_user->getRoleId() != $original_role_id) {
									clean_quick_jump_and_quick_add_cache($this->active_user);
                } // if
                
                if($this->request->isPageCall()) {
                  $this->response->redirectToUrl($this->active_user->getViewUrl());
                } else {
                  $this->response->respondWithData($this->active_user, array(
                    'as' => 'user',
                    'detailed' => true,
                  ));
                } // if
              } catch(Exception $e) {
                AngieApplication::revertCsfrProtectionCode();
                
                $this->response->exception($e);
              } // try
            } // if
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // edit_company_and_role
    
    /**
     * Export vCard
     */
    function export_vcard() {
      if($this->active_user->isLoaded()) {
        if($this->active_user->canView($this->logged_user)) {
          try{
            $this->active_user->toVCard();
            die();
          } catch(Exception $e) {
            $this->response->exception($e);
          } // try
        } else {
          $this->response->forbidden();
        } // if
      } else {
        $this->response->notFound();
      } // if
    } // export_vcard
    
    /**
     * Edit user password
     */
    function edit_password() {
      if($this->request->isAsyncCall() || $this->request->isMobileDevice()) {
        if($this->active_user->isLoaded()) {
          if($this->active_user->canChangePassword($this->logged_user)) {
            $user_data = $this->request->post('user');
            $this->response->assign('user_data', $user_data);
            
            if($this->request->isSubmitted(true, $this->response)) {
              try {
                $errors = new ValidationErrors();

                $password = array_var($user_data, 'password');
                $repeat_password = array_var($user_data, 'repeat_password');

                if(empty($password)) {
                  $errors->addError(lang('Password value is required'), 'password');
                } // if

                if(empty($repeat_password)) {
                  $errors->addError(lang('Repeat Password value is required'), 'repeat_password');
                } // if

                if(!$errors->hasErrors() && ($password !== $repeat_password)) {
                  $errors->addError(lang('Inserted values does not match'));
                } // if

                if($errors->hasErrors()) {
                  throw $errors;
                } // if

                $this->active_user->setPassword($user_data['password']);
                $this->active_user->save();

                if($this->request->isPageCall()) {
                  $this->response->redirectToUrl($this->active_user->getViewUrl());
                } else {
                  $this->response->respondWithData($this->active_user, array(
                    'as' => 'user',
                    'detailed' => true,
                  ));
                } // if
              } catch(Exception $e) {
                AngieApplication::revertCsfrProtectionCode();
                $this->response->exception($e);
              } // try
            } // if
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // edit_password
    
    /**
     * Return client company managers
     */
    function client_company_managers() {
      if($this->request->isAsyncCall() || $this->request->isApiCall()) {
        
        $client_company_manager_roles = Roles::findCompanyManagerRoles();

        // exclude company managers from owner company in case when it's something about finances
        if ($client_company_manager_roles && $this->active_company->isOwner() && $this->request->get('skip_owners_without_finances', false)) {
          foreach ($client_company_manager_roles as $key => $client_company_manager_role) {
            if (!$client_company_manager_role->getPermissionValue('can_manage_finances')) {
              unset($client_company_manager_roles[$key]);
            } // if
          } // foreach
        } // if
        
        if($client_company_manager_roles) {
          $client_company_managers = Users::getForSelectByConditions(array('company_id = ? AND id IN (?) AND role_id IN (?) AND state >= ?', $this->active_company->getId(), $this->logged_user->visibleUserIds($this->active_company), objects_array_extract($client_company_manager_roles, 'getId'), STATE_VISIBLE));
        } else {
          $client_company_managers = null;
        } // if
        
        $this->response->respondWithData($client_company_managers);
        
      } else {
        $this->response->badRequest();
      }//if
    }//getClientCompanyManagers
    
    
    /**
     * Show company users archive page
     */
    function archive() {
      if($this->request->isAsyncCall()) {
        $this->response->assign('archived_users', Users::findArchivedByCompany($this->active_company));
      } else {
        $this->response->badRequest();
      } // if
    } // archive
    
    /**
     * Delete user
     */
    function delete() {
      if(($this->request->isAsyncCall() || $this->request->isApiCall()) && $this->request->isSubmitted()) {
        if($this->active_user->isLoaded()) {
          if($this->active_user->canDelete($this->logged_user)) {
            try {
              $this->active_user->delete();
              $this->response->respondWithData($this->active_user, array(
                'as' => 'user',
                '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
    
    /**
     * Recent activities for selected user
     */
    function recent_activities() {
      if($this->request->isAsyncCall()) {
        if($this->active_user->isLoaded()) {
          if(!$this->active_user->canViewActivities($this->logged_user)) {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // recent_activities
    
    /**
     * Send welcome message
     */
    function send_welcome_message() {
      if($this->request->isAsyncCall()) {
        if($this->active_user->isLoaded()) {
          if($this->active_user->canSendWelcomeMessage($this->logged_user)) {
            $welcome_message_data = $this->request->post('welcome_message', array(
              'message' => ConfigOptions::getValueFor('welcome_message', $this->active_user),
            ));
            $this->response->assign('welcome_message_data', $welcome_message_data);
            
            if($this->request->isSubmitted()) {
              try {
                DB::beginWork('Sending welcome message @ ' . __CLASS__);

                $welcome_message = trim(array_var($welcome_message_data, 'message'));
                if($welcome_message) {
                  ConfigOptions::setValueFor('welcome_message', $this->active_user, $welcome_message);
                } else {
                  ConfigOptions::removeValuesFor($this->active_user, 'welcome_message');
                } // if

                $password = Authentication::getPasswordPolicy()->generatePassword();
                $this->active_user->setPassword($password);
      
                $this->active_user->save();

                $this->logged_user->notifier()->notifyUsers($this->active_user, $this->active_user, 'authentication/welcome', array(
                  'password' => $password,
                  'welcome_message' => $welcome_message,
                ));

                DB::commit('Welcome message sent @ ' . __CLASS__);

                $this->response->ok();
              } catch(Exception $e) {
                DB::rollback('Failed to send welcome message @ ' . __CLASS__);
                $this->response->exception($e);
              } // try
            } // if
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // send_welcome_message
    
    /**
     * Login as a selected user
     */
    function login_as() {
      if($this->active_user->isLoaded()) {
        if($this->active_user->canLoginAs($this->logged_user)) {
          if($this->request->isSubmitted()) {
            Authentication::getProvider()->logUserIn($this->active_user);
            $this->response->respondWithData($this->active_user, array(
              'as' => 'user', 
            ));
          } // if
        } else {
          $this->response->forbidden();
        } // if
      } else {
        $this->response->notFound();
      } // if
    } // login_as
    
  }