<?php

  /**
   * User state implementation
   *
   * @package activeCollab.modules.system
   * @subpackage models
   */
  class IUserStateImplementation extends IStateImplementation {
    
    // ---------------------------------------------------
    //  Permissions
    // ---------------------------------------------------
    
    /**
     * Returns true if $user can mark this object as archived
     *
     * @param User $user
     * @return boolean
     */
    function canArchive(User $user) {
      if($this->object->isNew() || $this->object->getId() == $user->getId()) {
        return false;
      } // if

      // users which are not visible can't be archived
      if ($this->object->getState() < STATE_VISIBLE) {
        return false;
      } // if

      return $this->object->isAdministrator() ? $user->isAdministrator() : $user->isPeopleManager();
    } // canArchive

    /**
     * Returns true if $user can mark this object as not archived
     *
     * @param User $user
     * @return boolean
     */
    function canUnarchive(User $user) {
      // cannot unarchive object which is not archived
      if ($this->object->getState() != STATE_ARCHIVED) {
        return false;
      } // if

      $company = $this->object->getCompany();

      // company does not exists so this user cannot be unarchived
      if (!($company instanceof Company && $company->isLoaded())) {
        return false;
      } // if

      // company is in trash so user cannot be untrashed
      if ($company->getState() < STATE_VISIBLE) {
        return false;
      } // if

      return $this->object->isAdministrator() ? $user->isAdministrator() : $user->isPeopleManager();
    } // canUnarchive

    /**
     * Returns true if $user can mark this object as trashed
     *
     * @param User $user
     * @return boolean
     */
    function canTrash(User $user) {
      if($this->object->isNew() || $this->object->getId() == $user->getId()) {
        return false;
      } // if

      // object is already in trash
      if ($this->object->getState() == STATE_TRASHED) {
        return false;
      } // if

      return $this->object->isAdministrator() ? $user->isAdministrator() : $user->isPeopleManager();
    } // canTrash

    /**
     * Returns true if $user can mark this object as untrashed
     *
     * @param User $user
     */
    function canUntrash(User $user) {
      if($this->object->isNew()) {
        return false;
      } // if

      // object is not trashed so it cannot be untrashed
      if ($this->object->getState() != STATE_TRASHED) {
        return false;
      } // if

      $company = $this->object->getCompany();

      // company is already deleted, so this user cannot be untrashed
      if (!($company instanceof Company && $company->isLoaded())) {
        return false;
      } // if

      // company is in trash so user cannot be untrashed
      if ($company->getState() == STATE_TRASHED) {
        return false;
      } // if

      return $this->object->isAdministrator() ? $user->isAdministrator() : $user->isPeopleManager();
    } // canUntrash

    /**
     * Restore object from trash
     */
    function untrash() {
      $original_state = $this->object->getState();

      if($original_state === STATE_TRASHED) {
        try {
          DB::beginWork('Restoring object from trash @ ' . __CLASS__);

          if ($this->object->getCompany()->getState() < STATE_VISIBLE) {
            $new_state = $this->object->getCompany()->getState();
            $original_state = $this->object->getOriginalState();

            $this->object->setState($new_state);
            $this->object->setOriginalState($original_state);
          } else {
            $new_state = $this->object->getOriginalState();

            $this->object->setState($new_state);
            $this->object->setOriginalState(null);
          }


          $this->object->save();

          DB::commit('Object restored from trash @ ' . __CLASS__);

          cache_clear();
        } catch(Exception $e) {
          DB::rollback('Failed to restore object from trash @ ' . __CLASS__);

          throw $e;
        } // try
      } else {
        throw new NotImplementedError(__CLASS__ . '::' . __METHOD__, 'Only objects marked as trashed can be restored from trash');
      } // if
    } // untrash

    /**
     * Returns true if $user can mark this object as deleted
     *
     * @param User $user
     * @return boolean
     */
    function canDelete(User $user) {
      if($this->object->isNew() || $this->object->getId() == $user->getId()) {
        return false;
      } // if
      
      return $this->object->isAdministrator() ? $user->isAdministrator() : $user->isPeopleManager();
    } // canDelete
    
  }