<?php

  /**
   * Framework level control tower implementation
   *
   * @package angie.frameworks.environment
   * @subpackage models
   */
  abstract class FwControlTower {

    /**
     * Show control tower for a given user
     *
     * @var User
     */
    protected $user;

    /**
     * Indicators array
     *
     * @var NamedList
     */
    protected $indicators;

    /**
     * List of tower widgets
     *
     * @var NamedList
     */
    protected $widgets;

    /**
     * Actions array
     *
     * @var NamedList
     */
    protected $actions;

    /**
     * Construct new control tower instance
     *
     * @param User $user
     */
    function __construct(User $user) {
      if($user instanceof User && $user->isAdministrator()) {
        $this->user = $user;
      } else {
        throw new InvalidInstanceError('user', $user, 'User');
      } // if

      $this->indicators = new NamedList();
      $this->widgets = new NamedList();
      $this->actions = new NamedList();
    } // __construct

    /**
     * Load control tower data
     */
    function load() {
      $scheduled_tasks_label = null;
      if(ConfigOptions::getValue('control_tower_check_scheduled_tasks')) {
        if(AngieApplication::areScheduledTasksRunning()) {
          $scheduled_tasks_running = true;
        } else {
          $scheduled_tasks_running = false;
        } // if
      } else {
        $scheduled_tasks_running = true;
      } // if

      $this->indicators()->add('scheduled_tasks', array(
        'label' => lang('Scheduled Tasks'),
        'value' => $scheduled_tasks_label,
        'url' => Router::assemble('scheduled_tasks_admin'),
        'is_ok' => $scheduled_tasks_running,
        'onclick' => new FlyoutCallback(),
      ));

      if(ConfigOptions::getValue('control_tower_check_disk_usage')) {
        $this->widgets()->add('disk_usage', array(
          'label' => lang('Disk Usage'),
          'renderer' => function() {
            $used_disk_space = (integer) AngieApplication::getUsedDiskSpace();
            $available_disk_space = (integer) AngieApplication::getDiskSpaceUsageLimit();

            if($available_disk_space) {
              $versobe_used_disk_space = lang('<span>:used</span> of <span>:available</span> used', array(
                'used' => format_file_size($used_disk_space),
                'available' => format_file_size($available_disk_space),
              ));
            } else {
              $versobe_used_disk_space = lang('<span>:used</span> of <span>Unlimited</span> used', array(
                'used' => format_file_size($used_disk_space),
              ));
            } // if

            $id = HTML::uniqueId('used_disk_space');

            return '<div class="verbose_disk_space_usage">' . $versobe_used_disk_space . '</div><div id="' . $id . '" used_disk_space="' . $used_disk_space . '" disk_space_usage_limit="' . $available_disk_space . '"></div><script type="text/javascript">$("#' . $id . '").diskSpaceUsage();</script>';
          }
        ));
      } // if

      $this->actions()->add('empty_cache', array(
        'label' => lang('Empty Cache'),
        'while_working' => lang('Emptying cache'),
        'url' => Router::assemble('control_tower_empty_cache'),
        'icon' => AngieApplication::getImageUrl('icons/16x16/proceed.png', ENVIRONMENT_FRAMEWORK, AngieApplication::INTERFACE_DEFAULT),
      ));

      $this->actions()->add('clear_compiled_templates', array(
        'label' => lang('Clear Compiled Templates'),
        'while_working' => lang('Clearing compiled templates'),
        'url' => Router::assemble('control_tower_delete_compiled_templates'),
        'icon' => AngieApplication::getImageUrl('icons/16x16/proceed.png', ENVIRONMENT_FRAMEWORK, AngieApplication::INTERFACE_DEFAULT),
      ));

      $this->actions()->add('rebuild_assets', array(
        'label' => lang('Rebuild Assets (Images, Fonts, Flash files etc)'),
        'while_working' => lang('Rebuilding application assets'),
        'url' => Router::assemble('control_tower_rebuild_images'),
        'icon' => AngieApplication::getImageUrl('icons/16x16/proceed.png', ENVIRONMENT_FRAMEWORK, AngieApplication::INTERFACE_DEFAULT),
      ));

      $this->actions()->add('rebuild_localization', array(
        'label' => lang('Rebuild Localization Dictionaries'),
        'while_working' => lang('Rebuilding localization dictionaries'),
        'url' => Router::assemble('control_tower_rebuild_localization'),
        'icon' => AngieApplication::getImageUrl('icons/16x16/proceed.png', ENVIRONMENT_FRAMEWORK, AngieApplication::INTERFACE_DEFAULT),
      ));

      EventsManager::trigger('on_load_control_tower', array(&$this, &$this->user));
    } // load

    /**
     * Cached badge value
     *
     * @var integer
     */
    private $badge_value = false;

    /**
     * Load and return badge value
     */
    function loadBadgeValue() {
      if($this->badge_value === false) {
        $badge_value = 0;

        if(ConfigOptions::getValue('control_tower_check_scheduled_tasks') && !AngieApplication::areScheduledTasksRunning()) {
          $badge_value++;
        } // if

        if(ConfigOptions::getValue('control_tower_check_disk_usage') && AngieApplication::isDiskSpaceUsageLimitReached()) {
          $badge_value++;
        } // if

        EventsManager::trigger('on_load_control_tower_badge', array(&$badge_value, &$this->user));

        $this->badge_value = $badge_value;
      } // if

      return $this->badge_value;
    } // loadBadgeValue

    /**
     * Control tower settings
     *
     * @var mixed
     */
    private $settings = false;

    /**
     * Get control tower settings
     *
     * @return array
     */
    function getSettings() {
      if($this->settings === false) {
        $system = lang('System');

        $settings = array(
          $system => array(
            'control_tower_check_scheduled_tasks' => array(
              'label' => lang('Check Scheduled Tasks'),
              'value' => ConfigOptions::getValue('control_tower_check_scheduled_tasks'),
            ),
            'control_tower_check_disk_usage' => array(
              'label' => lang('Check Disk Space Usage'),
              'value' => ConfigOptions::getValue('control_tower_check_disk_usage'),
            ),
          ),
        );

        EventsManager::trigger('on_load_control_tower_settings', array(&$settings, &$this->user));

        $this->settings = $settings;
      } // if

      return $this->settings;
    } // getSettings
    
    /**
     * Return indicators list
     *
     * @return NamedList
     */
    function &indicators() {
      return $this->indicators;
    } // indicators

    /**
     * Return widgets list
     *
     * @return NamedList
     */
    function &widgets() {
      return $this->widgets;
    } // widgets

    /**
     * Return actions list
     *
     * @return NamedList
     */
    function &actions() {
      return $this->actions;
    } // actions

    // ---------------------------------------------------
    //  Renderers
    // ---------------------------------------------------

    /**
     * Render control tower
     *
     * @return string
     */
    function render() {
      return '<div id="control_tower">' .
        $this->renderIndicators() .
        $this->renderWidgets() .
        $this->renderActions() .
      '</div>';
    } // render

    /**
     * Render indicators and counts
     *
     * @return string
     */
    private function renderIndicators() {
      if($this->indicators->count()) {
        $result = '<div class="control_tower_indicators control_tower_section">';

        foreach($this->indicators as $name => $indicator) {
          $classes = isset($indicator['is_ok']) && $indicator['is_ok'] ? 'control_tower_indicator ok' : 'control_tower_indicator nok';

          $result .= '<a href="' . clean($indicator['url']) . '" class="' . $classes . '" id="control_tower_indicator_' . clean($name) . '">
            <span class="indicator_label">' . clean($indicator['label']) . '</span>
            <span class="indicator_value"><span class="indicator_value_inner">' . ($indicator['value'] !== null ? clean($indicator['value']) : '') . '</span></span>
          </a>';
        } // foreach

        return $result . '</div>';
      } // if

      return '';
    } // renderIndicators

    /**
     * Render widgets
     *
     * @return string
     */
    function renderWidgets() {
      if($this->widgets->count()) {
        $result = '';

        foreach($this->widgets as $name => $widget) {
          $result .= '<h3 class="control_tower_section">' . clean($widget['label']) . '</h3>';
          $result .= '<div class="control_tower_widget control_tower_section" id="control_tower_widget_' . clean($name) . '">';

          if(isset($widget['renderer']) && $widget['renderer'] instanceof Closure) {
            $result .= $widget['renderer']->__invoke();
          } // if

          $result .= '</div>';
        } // foreach

        return $result;
      } // if

      return '';
    } // renderWidgets

    /**
     * Render actions
     *
     * @return string
     */
    private function renderActions() {
      if($this->actions->count()) {
        $result = '<h3 class="control_tower_section">' . lang('Quick Administration Actions') . '</h3>';
        $result .= '<div class="control_tower_actions control_tower_section">';
        $result .= '<table class="common" cellspacing="0">';

        foreach($this->actions() as $name => $action) {
          $result .= '<tr id="control_tower_action_' . clean($name) . '">
            <td class="submit"><a href="' . clean($action['url']) . '" while_working_message="' . clean($action['while_working']) . '"><img src="' . clean($action['icon']) . '"></a></td>
            <td class="action_title">' . clean($action['label']) . '</td>
          </tr>';
        } // foreach

        return "$result</table></div>";
      } // if

      return '';
    } // renderActions

  }