<?php

  // Inherit projects controller
  AngieApplication::useController('projects', SYSTEM_MODULE);

  /**
   * Single project controller
   *
   * @package activeCollab.modules.system
   * @subpackage controllers
   */
  class ProjectController extends ProjectsController {
    
    /**
     * Active project
     *
     * @var Project
     */
    protected $active_project;
    
    /**
     * Complete controller delegate
     *
     * @var CompleteController
     */
    protected $complete_delegate;
    
    /**
     * State controller delegate
     *
     * @var StateController
     */
    protected $state_delegate;
    
    /**
     * Avatar controller delegate
     * 
     * @var ProjectAvatarController
     */
    protected $avatar_delegate;
    
    /**
     * Object tracking delegate controller
     *
     * @var ObjectTrackingController
     */
    protected $object_tracking_delegate;
    
    /**
     * Labels controller delegate
     * 
     * @var LabelsController
     */
    protected $labels_delegate;
    
    /**
     * Categories delegate controller instance
     *
     * @var CategoriesController
     */
    protected $categories_delegate;

    /**
     * Activity logs delegate
     *
     * @var ActivityLogsController
     */
    protected $activity_logs_delegate;
    
    /**
     * Invoice controller delegate
     * 
     * @var InvoiceBasedOnController
     */
    protected $invoice_delegate;
    
    /**
     * Actions exposed through API
     *
     * @var array
     */
    protected $api_actions = array('index', 'add', 'edit', 'edit_status', 'delete', 'user_tasks');
    
    /**
     * Construct project controller
     *
     * @param Request $parent
     * @param mixed $context
     */
    function __construct(Request $parent, $context = null) {
      parent::__construct($parent, $context);
      
      if($this->getControllerName() == 'project') {
        $this->complete_delegate = $this->__delegate('complete', COMPLETE_FRAMEWORK_INJECT_INTO, 'project');
        $this->state_delegate = $this->__delegate('state', ENVIRONMENT_FRAMEWORK_INJECT_INTO, 'project');
        $this->avatar_delegate = $this->__delegate('project_avatar', AVATAR_FRAMEWORK_INJECT_INTO, 'project');
        $this->categories_delegate = $this->__delegate('categories', CATEGORIES_FRAMEWORK_INJECT_INTO, 'project');
        $this->labels_delegate = $this->__delegate('labels', LABELS_FRAMEWORK_INJECT_INTO, 'project');
        $this->activity_logs_delegate = $this->__delegate('activity_logs', ACTIVITY_LOGS_FRAMEWORK_INJECT_INTO, 'project');
        
        if(AngieApplication::isModuleLoaded('tracking')) {
          $this->object_tracking_delegate = $this->__delegate('object_tracking', TRACKING_MODULE, 'project');
        } // if
        
        if(AngieApplication::isModuleLoaded('invoicing')) {
          $this->invoice_delegate = $this->__delegate('invoice_based_on', INVOICING_MODULE, 'project');
        } // if
      } // if
    } // __construct
    
    /**
     * Prepare controller
     */
    function __before() {
      parent::__before();
      
      $this->wireframe->actions->clear();
      
      $project_slug = $this->request->get('project_slug');
      
      if($project_slug) {
        if(is_numeric($project_slug)) {
          $this->active_project = Projects::findById($project_slug);
        } else {
          $this->active_project = Projects::findBySlug($project_slug);
        } // if
      } // if
      
      if($this->active_project instanceof Project && $this->active_project->isLoaded()) {
        if ($this->active_project->getState() < STATE_TRASHED) {
          $this->response->notFound();
        } // if

        if(!$this->active_project->canView($this->logged_user)) {
          $this->response->forbidden();
        } // if

        // clear tabs
        $this->wireframe->tabs->clear();
        $this->wireframe->breadcrumbs->add('project', $this->active_project->getName(), $this->active_project->getViewUrl());

        // if project is in trash
        if ($this->active_project->getState() == STATE_TRASHED) {
          if (!(in_array($this->request->getAction(), array('index', 'project_state_untrash')) && $this->getControllerName() == 'project')) {
            $this->response->notFound();
          } else {
            $this->wireframe->tabs->add('overview', $this->active_project->getName(), $this->active_project->getViewUrl());
          } // if

        // if project is not in trash
        } else {
          if ($this->active_project->getState() == STATE_ARCHIVED) {
            $this->wireframe->breadcrumbs->add('archive', lang('Archive'), Router::assemble('projects_archive'));
          } // if

          // Tabs
          foreach($this->active_project->getTabs($this->logged_user, AngieApplication::getPreferedInterface()) as $tab_name => $tab) {
            if($tab['text'] == '-') {
              $this->wireframe->tabs->addSeparator();
            } else {
              $this->wireframe->tabs->add($tab_name, $tab['text'], $tab['url'], $tab['icon']);
            } // if
          } // foreach
        } // if

        if($this->request->isWebBrowser()) {
          $this->wireframe->tabs->setCurrentTab('overview');
        } // if
        
        $this->wireframe->javascriptAssign('active_project_id', $this->active_project->getId());
        
      // New project
      } else {
        if($this->getControllerName() == 'project') {
          $this->active_project = new Project();
        } else {
          $this->response->notFound();
        } // if
      } // if
      
      $this->response->assign('active_project', $this->active_project);
      
      if($this->categories_delegate instanceof CategoriesController) {
        $this->categories_delegate->__setProperties(array(
          'routing_context' => 'project', 
          'category_class' => 'ProjectCategory',
          'routing_context_params' => array('project_slug' => $this->active_project->getSlug()),
          'active_object' => &$this->active_project
        ));
      } // if
      
      if($this->complete_delegate instanceof CompleteController) {
        $this->complete_delegate->__setProperties(array(
          'active_object' => &$this->active_project,
        ));
      } // if
      
      if ($this->labels_delegate instanceof LabelsController) {
        $this->labels_delegate->__setProperties(array(
          'active_object' => &$this->active_project
        ));
      } // if
      
      if($this->state_delegate instanceof StateController) {
        $this->state_delegate->__setProperties(array(
          'active_object' => &$this->active_project, 
        ));
      } // if
      
      if($this->avatar_delegate instanceof ProjectAvatarController) {
        $this->avatar_delegate->__setProperties(array(
          'active_object' => &$this->active_project
        ));
      } // if

      if($this->activity_logs_delegate instanceof ActivityLogsController) {
        $this->activity_logs_delegate->__setProperties(array(
          'show_activities_in' => &$this->active_project
        ));
      } // if
      
      if($this->object_tracking_delegate instanceof ObjectTrackingController) {
        $this->object_tracking_delegate->__setProperties(array(
          'active_tracking_object' => &$this->active_project
        ));
      } // if
      
      if($this->invoice_delegate instanceof InvoiceBasedOnController) {
        $this->invoice_delegate->__setProperties(array(
          'active_object' => &$this->active_project
        ));
      } // if
      
    } // __before
    
    /**
     * Show project overview page
     */
    function index() {
      if($this->active_project->isLoaded()) {
        $this->wireframe->print->enable();
        
        // Just serve the data
        if($this->request->isApiCall()) {
          $this->response->respondWithData($this->active_project, array(
            'as' => 'project', 
            'detailed' => true, 
          ));
        
        // Phone user
        } elseif($this->request->isPhone()) {
          $this->wireframe->setPageObject($this->active_project, $this->logged_user);
          
          if($this->active_project->canEdit($this->logged_user)) {
            $this->wireframe->actions->add('edit', lang('Edit'), $this->active_project->getEditUrl(), array(
              'icon' => AngieApplication::getImageUrl('layout/buttons/edit.png', SYSTEM_MODULE, AngieApplication::INTERFACE_PHONE),
              'primary' => true
            ));
          } // if
          
          $this->wireframe->tabs->add('project_people', lang('People'), Router::assemble('project_people', array('project_slug' => $this->active_project->getSlug())), AngieApplication::getImageUrl('icons/listviews/project-people.png', SYSTEM_MODULE, AngieApplication::INTERFACE_PHONE), true);
          
        // Brief
        } elseif($this->request->get('brief') || $this->active_project->getState() == STATE_TRASHED || $this->request->isQuickViewCall()) {
          if ($this->request->isSingleCall() || $this->request->isQuickViewCall()) {
            $this->setView('brief');
          } else {
            if ($this->request->isSingleCall()) {
              $this->setView('brief');
  
              $project_brief_stats = array();
              EventsManager::trigger('on_project_brief_stats', array(&$this->active_project, &$project_brief_stats, &$this->logged_user));
  
              if(Projects::canAdd($this->logged_user) && $this->active_project->getState() != STATE_ARCHIVED) {
                $this->wireframe->actions->add('new_project', lang('New Project'), Router::assemble('projects_add'), array(
                  'onclick' => new NewProjectCallback(),
                  'icon' => AngieApplication::getImageUrl('layout/button-add.png', ENVIRONMENT_FRAMEWORK, AngieApplication::getPreferedInterface()),
                  'primary' => true
                ));
              } // if
  
              $this->response->assign(array(
                'project_brief_stats' => $project_brief_stats
              ));
            } else {
              if ($this->active_project->getState() == STATE_ARCHIVED) {
                parent::archive();
                parent::render(get_view_path('archive', 'projects', SYSTEM_MODULE));
              } else {
                parent::index();
                parent::render(get_view_path('index', 'projects', SYSTEM_MODULE));
              } // if
            } // if
          }//if
  
        // Full project overview
        } else {
          
          $this->wireframe->setPageObject($this->active_project, $this->logged_user);

          if($this->logged_user->isFeedUser()) {
            $this->wireframe->addRssFeed(
              lang('[:project] Recent Activities', array('project' => $this->active_project->getName())),
              $this->active_project->getRssUrl($this->logged_user)
            );
          } // if

          $day_types = get_day_project_object_types();
          
          $home_sidebars = array();
          EventsManager::trigger('on_project_overview_sidebars', array(&$home_sidebars, &$this->active_project, &$this->logged_user));

          $this->response->assign(array(
            'project_company' => $this->active_project->getCompany(),
            'late_and_today' => ProjectObjects::findLateAndToday($this->logged_user, $this->active_project, $day_types),
            'upcoming_objects' => ProjectObjects::findUpcoming($this->logged_user, $this->active_project, $day_types),
            'home_sidebars' => $home_sidebars
          ));
        } // if
      } else {
        $this->response->notFound();
      } // if
    } // index
    
    /**
     * Show user subscriptions on objects in selected project
     */
    function user_subscriptions() {
      $offset = ($this->request->get('offset')) ? $this->request->get('offset') : 0;
      $subscriptions = Subscriptions::showByUser($this->logged_user, $this->active_project);
      $temp_sub = array();
      $show_per_number = 50;
      for ($i = $offset * $show_per_number; $i < ($offset*$show_per_number+$show_per_number); $i++) {
        if ($subscriptions[$i]) {
          $temp_sub[] = $subscriptions[$i];
        } else {
          break;
        } //if
      } //for
      $this->response->assign('subscriptions', $temp_sub);
      if ($this->request->isAsyncCall() && $offset > 0) {
        if (empty($temp_sub)) {
          die('empty');
        }
        $this->setView(get_view_path('_user_subscriptions_loop',$this->getControllerName(),SYSTEM_MODULE));
      } else {
        $this->response->assign(array(
          'show_more_results_url'     => Router::assemble(project_user_subscriptions, array('project_slug' => $this->active_project->getSlug())),
          'mass_unsubscribe_url' => Router::assemble(project_user_subscriptions_mass_unsubscribe, array('project_slug' => $this->active_project->getSlug()))
        ));
      } //if
    } // user_subscriptions
    
    /**
     * Async mass unsubscription
     */
    function user_subscriptions_mass_unsubscribe() {
      if ($this->request->isAsyncCall()) {
        try {
          if (Subscriptions::massUnsubscribe($this->request->get('unsubscribes'),$this->logged_user)) {
            die('ok');
          } else {
            die('error');
          } //if
        } catch (Exception $e) {
          $this->response->exception($e);
        } //try
      } else {
        $this->response->badRequest();
      } //if
    } //user_subscriptions_mass_unsubscribe
    
    /**
     * Show tasks for a given user
     */
    function user_tasks() {
      $this->response->assign(array(
        'assignments' =>  $this->active_project->getUserAssignments($this->logged_user), 
        'project_slugs' => Projects::getIdSlugMap(), 
        'task_url' => AngieApplication::isModuleLoaded('tasks') ? Router::assemble('project_task', array('project_slug' => '--PROJECT_SLUG--', 'task_id' => '--TASK_ID--')) : '', 
        'task_subtask_url' => AngieApplication::isModuleLoaded('tasks') ? Router::assemble('project_task_subtask', array('project_slug' => '--PROJECT_SLUG--', 'task_id' => '--TASK_ID--', 'subtask_id' => '--SUBTASK_ID--')) : '', 
        'todo_url' => AngieApplication::isModuleLoaded('todo') ? Router::assemble('project_todo_list', array('project_slug' => '--PROJECT_SLUG--', 'todo_list_id' => '--TODO_LIST_ID--')) : '', 
        'todo_subtask_url' => AngieApplication::isModuleLoaded('todo') ? Router::assemble('project_todo_list', array('project_slug' => '--PROJECT_SLUG--', 'todo_list_id' => '--TODO_LIST_ID--', 'subtask_id' => '--SUBTASK_ID--')) : '', 
        'labels' => Labels::getIdDetailsMap('AssignmentLabel'),
      ));
    } // user_tasks
    
    /**
     * Process add project form
     */
    function add() {
      if($this->request->isAsyncCall() || $this->request->isMobileDevice() || ($this->request->isApiCall() && $this->request->isSubmitted())) {
        if(Projects::canAdd($this->logged_user)) {
          $project_data = $this->request->post('project', array(
            'company_id' => $this->owner_company->getId(), 
            'leader_id' => $this->logged_user->getId(), 
            'first_milestone_starts_on' => new DateValue(),
            'currency_id' => Currencies::getDefaultId(), 
          ));
          
          //  If project is based on a project request
          $project_request_id = $this->request->getId('project_request_id');
          if($project_request_id) {
            $project_request = ProjectRequests::findById($project_request_id);
            
            if($project_request instanceof ProjectRequest) {
              $project_data['based_on_id'] = $project_request_id;
              $project_data['based_on_type'] = get_class($project_request);
              $project_data['name'] = $project_request->getName();

              $verbose_custom_fields = $project_request->getVerboseCustomFields();
              if ($verbose_custom_fields) {
                $overview_data = implode("<br/><br/>", array($project_request->getBody(), $verbose_custom_fields));
              } else {
                $overview_data = $project_request->getBody();
              } // if

              $project_data['overview'] = HTML::toRichText($overview_data);
            } else {
              $this->response->notFound();
            } // if
          } // if
          
          // If project is based on a quote
          if(AngieApplication::isModuleLoaded('invoicing')) {
            $quote_id = $this->request->getId('quote_id');
            if($quote_id) {
              $quote = Quotes::findById($quote_id);
              
              if($quote instanceof Quote) {
                $project_data['based_on_id'] = $quote_id;
                $project_data['based_on_type'] = get_class($quote);
                $project_data['name'] = $quote->getName();
                $project_data['overview'] = $quote->getNote();
                $project_data['company_id'] = $quote->getCompanyId();
                $project_data['currency_id'] = $quote->getCurrencyId();

                $project_data['budget'] = $quote->getTotal();
              } else {
                $this->response->notFound();
              } // if
            } // if
          } // if

          $based_on = null;
          if(isset($project_data['based_on_type']) && $project_data['based_on_type'] && isset($project_data['based_on_id']) && $project_data['based_on_id']) {
            $based_on_class = $project_data['based_on_type'];
            if(class_exists($based_on_class)) {
              $based_on = new $based_on_class($project_data['based_on_id']);

              if(!($based_on instanceof IProjectBasedOn) || $based_on->isNew()) {
                $based_on = null;
              }  // if
            } // if
          } // if

          $this->response->assign(array(
            'project_data' => $project_data,
            'based_on' => $based_on
          ));
          
          if($this->request->isSubmitted()) {
            try {
              $leader = isset($project_data['leader_id']) && $project_data['leader_id'] ? Users::findById($project_data['leader_id']) : null;
              $company = isset($project_data['company_id']) && $project_data['company_id'] ? Companies::findById($project_data['company_id']) : null;
              $category = isset($project_data['category_id']) && $project_data['category_id'] ? Categories::findById($project_data['category_id']) : null;
              $template = isset($project_data['project_template_id']) && (integer) $project_data['project_template_id'] ? Projects::findById($project_data['project_template_id']) : null;
              $first_milestone_starts_on = isset($project_data['first_milestone_starts_on']) && $project_data['first_milestone_starts_on'] ? DateValue::makeFromString($project_data['first_milestone_starts_on']) : null;
              
              $create_project_instantly = $this->request->isApiCall() || $this->request->isPhone() ? true : false;
              
              $created_project = ProjectCreator::create(array_var($project_data, 'name'), array(
                'slug' => isset($project_data['slug']) && $project_data['slug'] ? $project_data['slug'] : null,
                'leader' => $leader, 
                'company' => $company, 
                'category' => $category, 
                'based_on' => $based_on, 
                'template' => $template,
                'overview' => $project_data['overview'],
                'first_milestone_starts_on' => $first_milestone_starts_on, 
                'label_id' => isset($project_data['label_id']) && $project_data['label_id'] ? $project_data['label_id'] : 0, 
                'budget' => isset($project_data['budget']) ? (float) $project_data['budget'] : null, 
                'currency_id' => isset($project_data['currency_id']) ? (integer) $project_data['currency_id'] : Currencies::getDefaultId(), 
                'custom_field_1' => isset($project_data['custom_field_1']) && $project_data['custom_field_1'] ? $project_data['custom_field_1'] : null,
                'custom_field_2' => isset($project_data['custom_field_2']) && $project_data['custom_field_2'] ? $project_data['custom_field_2'] : null,
                'custom_field_3' => isset($project_data['custom_field_3']) && $project_data['custom_field_3'] ? $project_data['custom_field_3'] : null,
              ), $create_project_instantly);

              // create milestones based on quote items
              if ($based_on && $based_on instanceof Quote && AngieApplication::isModuleLoaded('invoicing') && array_var($project_data, 'create_milestones', false)) {
                $quote_items = $based_on->getItems();
                if (is_foreachable($quote_items)) {
                  foreach ($quote_items as $quote_item) {
                    DB::beginWork('Creating milestone based on quote @ ' . __CLASS__);

                    $milestone = new Milestone();
                    $milestone->setName($quote_item->getDescription());
                    $milestone->setProjectId($created_project->getId());
                    $milestone->setCreatedBy($this->logged_user);
                    $milestone->setState($created_project->getState());
                    $milestone->setVisibility($created_project->getDefaultVisibility());
                    $milestone->save();

                    DB::commit('Milestone saved @ ' . __CLASS__);

                    $milestone->subscriptions()->set(array($created_project->getLeaderId()));
                  } // foreach
                } // if
              } // if
              
              clean_quick_jump_and_quick_add_cache();
              
              if ($this->request->isPageCall()) {
                $this->flash->success('Project ":name" has been created', array('name' => $created_project->getName()));
                $this->response->redirectToUrl($created_project->getViewUrl());
              } else {
                $this->response->respondWithData($created_project, array(
                  'as' => 'project', 
                  'detailed' => true, 
                ));
              } //if
            } catch(Exception $e) {
              DB::rollback('Failed to create project @ ' . __CLASS__);
              $this->response->exception($e);
            } // try
          } // if
        } else {
          $this->response->forbidden();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // add
    
    /**
     * Additional post creation step
     */
    function additional_step() {
      if($this->request->isAsyncCall() && $this->request->isSubmitted()) {
        try {
          ProjectCreator::executeAdditionalStep($this->request->get('step'), $this->active_project, $this->logged_user);
          
          $this->response->respondWithData($this->active_project, array(
            'as' => 'project', 
            'detailed' => true, 
          ));
        } catch(Exception $e) {
          $this->response->exception($e);
        } // try
      } else {
        $this->response->badRequest();
      } // if
    } // additional_step
    
    /**
     * Update project
     */
    function edit() {
      if($this->request->isAsyncCall() || $this->request->isMobileDevice() || ($this->request->isApiCall() && $this->request->isSubmitted())) {
        if($this->active_project->isLoaded()) {
          if($this->active_project->canEdit($this->logged_user)) {
            $project_data = $this->request->post('project', array(
              'name' => $this->active_project->getName(),
              'overview' => $this->active_project->getOverview(),
              'default_visibility' => $this->active_project->getDefaultVisibility(),
              'leader_id' => $this->active_project->getLeaderId(),
              'category_id' => $this->active_project->getCategoryId(),
              'company_id' => $this->active_project->getCompanyId(),
              'default_visibility' => $this->active_project->getDefaultVisibility(),
              'label_id' => $this->active_project->getLabelId(),
              'exclude_ids' => $this->active_project->getLeaderId(), 
              'custom_field_1' => $this->active_project->getCustomField1(),
              'custom_field_2' => $this->active_project->getCustomField2(),
              'custom_field_3' => $this->active_project->getCustomField3(),
            ));
            
            // Manipulate with budget attribute based on user permissions
            if($this->logged_user->canSeeProjectBudgets()) {
              if(!isset($project_data['budget'])) {
                $project_data['budget'] = $this->active_project->getBudget();
              } // if
              
              if(!isset($project_data['currency_id'])) {
                $project_data['currency_id'] = $this->active_project->getCurrencyId();
              } // if
            } else {
              if(isset($project_data['budget'])) {
                unset($project_data['budget']);
              } // if
              
              if(isset($project_data['currency_id'])) {
                unset($project_data['currency_id']);
              } // if
            } // if
            
            $this->response->assign('project_data', $project_data);
            
            if($this->request->isSubmitted()) {
              try {
                DB::beginWork('Updating project @ ' . __CLASS__);
                
                $this->active_project->setAttributes($project_data);
                
                if($this->active_project->isModified('leader_id') && $this->active_project->getLeaderId()) {
                  $leader = Users::findById($this->active_project->getLeaderId());
                  if($leader instanceof User) {
                    if(!$this->active_project->users()->isMember($leader)) {
                      $this->active_project->users()->add($leader);
                    } // if
                    
                    $this->active_project->setLeader($leader);
                  } // if
                } // if
                
                if($this->active_project->isModified('company_id')) {
                  cache_remove('project_icons');
                } // if
                
                $this->active_project->save();
                
                DB::commit('Project updated @ ' . __CLASS__);
                
                clean_quick_jump_and_quick_add_cache();
                
                if($this->request->isPageCall()) {
                  $this->flash->success('Project ":name" has been edited', array('name' => $this->active_project->getName()));
                  $this->response->redirectToUrl($this->active_project->getViewUrl());
                } else {
                  $this->response->respondWithData($this->active_project, array(
                    'as' => 'project', 
                    'detailed' => true, 
                  ));
                } //if
              } catch(Exception $e) {
                DB::rollback('Failed to update project @ ' . __CLASS__);
                $this->response->exception($e);
              } // try
            } // if
          } else {
            $this->response->forbidden();
          } // if
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // edit
    
    /**
     * Delete project
     */
    function delete() {
      if(($this->request->isAsyncCall() || $this->request->isApiCall()) && $this->request->isSubmitted()) {
        if($this->active_project->isLoaded()) {
          if($this->active_project->canDelete($this->logged_user)) {
            try {
              $this->active_project->delete();
              clean_quick_jump_and_quick_add_cache();
              
              $this->response->respondWithData($this->active_project, array(
                'as' => 'project', 
                '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
    
    /**
     * Show project settings index page
     */
    function settings() {
      if($this->request->isAsyncCall() || ($this->request->isApiCall() && $this->request->isSubmitted())) {
        $settings_data = $this->request->post('settings');
      
        if(empty($settings_data)) {
          if(ConfigOptions::hasValueFor('default_project_object_visibility', $this->active_project)) {
            $default_project_object_visibility = ConfigOptions::getValueFor('default_project_object_visibility', $this->active_project);
          } else {
            $default_project_object_visibility = null;
          } // if

          if(ConfigOptions::hasValueFor('clients_can_delegate_to_employees', $this->active_project)) {
            $clients_can_delegate_to_employees = ConfigOptions::getValueFor('clients_can_delegate_to_employees', $this->active_project);;
          } else {
            $clients_can_delegate_to_employees = null;
          } // if

          if(AngieApplication::isModuleLoaded('tracking') && ConfigOptions::hasValueFor('default_billable_status', $this->active_project)) {
            $default_billable_status = (boolean) ConfigOptions::getValueFor('default_billable_status', $this->active_project); // yes_no_default works only with boolean values
          } else {
            $default_billable_status = null;
          } // if
          
          $settings_data = array(
            'use_custom_tabs' => ConfigOptions::hasValueFor('project_tabs', $this->active_project),
            'project_tabs' => ConfigOptions::getValueFor('project_tabs', $this->active_project), 
            'default_project_object_visibility' => $default_project_object_visibility,
            'clients_can_delegate_to_employees' => $clients_can_delegate_to_employees,
            'default_billable_status' => $default_billable_status,
          );
        } // if
        
        $this->response->assign(array(
          'settings_data' => $settings_data,
          'default_clients_can_delegate_to_employees' => ConfigOptions::getValue('clients_can_delegate_to_employees'),
          'default_default_billable_status' => AngieApplication::isModuleLoaded('tracking') ? ConfigOptions::getValue('default_billable_status') : 1,
        ));
        
        if($this->request->isSubmitted()) {
          try {
            if(array_var($settings_data, 'use_custom_tabs')) {
              ConfigOptions::setValueFor('project_tabs', $this->active_project, array_var($settings_data, 'project_tabs'));
            } else {
              ConfigOptions::removeValuesFor($this->active_project, 'project_tabs');
            } // if
            
            if((string) $settings_data['default_project_object_visibility'] === '') {
              ConfigOptions::removeValuesFor($this->active_project, 'default_project_object_visibility');
            } else {
              ConfigOptions::setValueFor('default_project_object_visibility', $this->active_project, (integer) $settings_data['default_project_object_visibility']);
            } // if

            if((string) $settings_data['clients_can_delegate_to_employees'] === '') {
              ConfigOptions::removeValuesFor($this->active_project, 'clients_can_delegate_to_employees');
            } else {
              ConfigOptions::setValueFor('clients_can_delegate_to_employees', $this->active_project, (integer) $settings_data['clients_can_delegate_to_employees']);
            } // if

            if(AngieApplication::isModuleLoaded('tracking')) {
              if((string) $settings_data['default_billable_status'] === '') {
                ConfigOptions::removeValuesFor($this->active_project, 'default_billable_status');
              } else {
                ConfigOptions::setValueFor('default_billable_status', $this->active_project, (integer) $settings_data['default_billable_status']);
              } // if
            } // if
                        
            $response = array(
              'settings' => array(
                'tabs'        => $this->active_project->getTabs($this->logged_user, AngieApplication::INTERFACE_DEFAULT, false),
                'visibility'  => ConfigOptions::getValueFor('default_project_object_visibility', $this->active_project)
              ),
              'project' => $this->active_project
            );
            
            clean_quick_jump_and_quick_add_cache();
            
            $this->response->respondWithData($response, array( 
              'detailed' => true, 
            ));
          } catch(Exception $e) {
            $this->response->exception($e);
          } // try
        } // if
      } else {
        $this->response->badRequest();
      } // if
    } // settings

    /**
     * List meta information about all project attachments
     */
    function attachments() {
      if($this->request->isApiCall()) {
        $this->response->respondWithData(Attachments::findForApiByProject($this->active_project), array(
          'as' => 'attachments',
        ));
      } else {
        $this->response->badRequest();
      } // if
    } // attachments

    /**
     * Return all project comments in a single API response
     */
    function comments() {
      if($this->request->isApiCall()) {
        $this->response->respondWithData(Comments::findForApiByProject($this->active_project), array(
          'as' => 'comments',
        ));
      } else {
        $this->response->badRequest();
      } // if
    } // comments

    /**
     * Return all project comments in a single API response
     */
    function subtasks() {
      if($this->request->isApiCall()) {
        $this->response->respondWithData(Subtasks::findForApiByProject($this->active_project), array(
          'as' => 'subtasks',
        ));
      } else {
        $this->response->badRequest();
      } // if
    } // subtasks
    
    /**
     * Serve iCal data
     */
    function ical() {
      if ($this->logged_user->isFeedUser()) {
        $filter = $this->logged_user->projects()->getVisibleTypesFilterByProject($this->active_project, get_completable_project_object_types());
        if($filter) {
          $objects = ProjectObjects::find(array(
            'conditions' => array($filter . ' AND completed_on IS NULL AND state >= ? AND visibility >= ?', STATE_VISIBLE, $this->logged_user->getMinVisibility()),
            'order' => 'priority DESC',
          ));

          render_icalendar($this->active_project->getName(), $objects);
          die();
        } else {
          $this->response->notFound();
        } // if
      } else {
        $this->response->forbidden();
      } //if
    } // ical
    
    /**
     * Show iCal subscribe page
     */
    function ical_subscribe() {
      if ($this->logged_user->isFeedUser()) {
        $this->wireframe->hidePrintButton();
        $feed_token  = $this->logged_user->getFeedToken();

        $ical_url = Router::assemble('project_ical', array('project_slug' => $this->active_project->getSlug(), 'auth_api_token' => $feed_token));

        $ical_subscribe_url = str_replace(array('http://', 'https://'), array('webcal://', 'webcal://'), $ical_url);

        $this->response->assign(array(
          'ical_url' => $ical_url,
          'ical_subscribe_url' => $ical_subscribe_url
        ));
      } else {
        $this->response->forbidden();
      } //if
    } // ical_subscribe

  }