<?php

  /**
   * System module definition
   *
   * @package activeCollab.modules.system
   */
  class SystemModule extends AngieModule {
    
    /**
     * Plain module name
     *
     * @var string
     */
    protected $name = 'system';
    
    /**
     * Module version
     *
     * @var string
     */
    protected $version = '3.0';
    
    // ---------------------------------------------------
    //  Events and Routes
    // ---------------------------------------------------
    
    /**
     * Define module routes
     */
    function defineRoutes() {

      Router::map('new_version_details', 'admin/new-version', array('controller' => 'admin', 'action' => 'new_version'));
      Router::map('save_license_details', 'admin/save-license-details', array('controller' => 'admin', 'action' => 'save_license_details'));

      // API specific
      Router::map('project_roles_info', 'info/roles/project', array('controller' => 'roles_info', 'action' => 'project_roles'));
      Router::map('project_role_info', 'info/roles/project/:role_id', array('controller' => 'roles_info', 'action' => 'project_role'), array('role_id' => Router::MATCH_ID));
      
      // Dashboard
      Router::map('quick_jump', 'quick-jump', array('controller' => 'backend', 'action' => 'quick_jump'));
      Router::map('quick_add', 'quick-add', array('controller' => 'backend', 'action' => 'quick_add'));
      Router::map('my_tasks', 'my-tasks', array('controller' => 'backend', 'action' => 'my_tasks'));
      
      // Search
      Router::map('quick_backend_search', 'search/quick', array('controller' => 'backend_search', 'action' => 'quick_search'));
      
      // People
      Router::map('people', 'people', array('controller' => 'people', 'action' => 'index'));
      Router::map('people_printable', 'people/printable', array('controller' => 'people', 'action' => 'index_printable'));
      Router::map('people_import_vcard', 'people/import-vcard', array('controller' => 'people', 'action' => 'import_vcard'));
//      Router::map('people_export_vcard', 'people/export-vcard', array('controller' => 'people', 'action' => 'export_vcard'));
//      Router::map('people_export_individual_vcards', 'people/export-individual-vcard', array('controller' => 'people', 'action' => 'export_individual_vcards'));
      Router::map('people_archive', 'people/archive', array('controller' => 'people', 'action' => 'archive'));
      Router::map('people_archive_printable', 'people/archive/printable', array('controller' => 'people', 'action' => 'archive_printable'));
      
      Router::map('people_mass_edit', 'people/mass-edit', array('controller' => 'people', 'action' => 'mass_edit'));
     
      Router::map('people_companies_add', 'people/add-company', array('controller' => 'companies', 'action' => 'add'));
      Router::map('people_company', 'people/:company_id', array('controller' => 'companies', 'action' => 'view'), array('company_id' => Router::MATCH_ID));
      Router::map('people_company_details', 'people/company_details', array('controller' => 'companies', 'action' => 'company_details'));
      Router::map('people_company_edit', 'people/:company_id/edit', array('controller' => 'companies', 'action' => 'edit'), array('company_id' => Router::MATCH_ID));
      Router::map('people_company_export_vcard', 'people/:company_id/export-vcard', array('controller' => 'companies', 'action' => 'export_vcard'), array('company_id' => Router::MATCH_ID));
      Router::map('people_company_delete', 'people/:company_id/delete', array('controller' => 'companies', 'action' => 'delete'), array('company_id' => Router::MATCH_ID));
      Router::map('people_company_edit_logo', 'people/:company_id/edit-logo', array('controller' => 'companies', 'action' => 'edit_logo'), array('company_id' => Router::MATCH_ID));
      Router::map('people_company_delete_logo', 'people/:company_id/delete-logo', array('controller' => 'companies', 'action' => 'delete_logo'), array('company_id' => Router::MATCH_ID));
      
      AngieApplication::getModule('environment')->defineStateRoutesFor('people_company', 'people/:company_id', 'companies', SYSTEM_MODULE, array('company_id' => Router::MATCH_ID));
      AngieApplication::getModule('avatar')->defineAvatarRoutesFor('people_company', 'people/:company_id', 'companies', SYSTEM_MODULE, array('company_id' => Router::MATCH_ID));
      
      Router::map('people_company_projects', 'people/:company_id/projects', array('controller' => 'company_projects', 'action' => 'index'), array('company_id' => Router::MATCH_ID));
      Router::map('people_company_projects_archive', 'people/:company_id/projects/archive', array('controller' => 'company_projects', 'action' => 'archive'), array('company_id' => Router::MATCH_ID));
      
      Router::map('people_company_users', 'people/:company_id/users', array('controller' => 'users', 'action' => 'index'), array('company_id' => Router::MATCH_ID));
      Router::map('people_company_users_archive', 'people/:company_id/users/archive', array('controller' => 'users', 'action' => 'archive'), array('company_id' => Router::MATCH_ID));
      
      Router::map('people_company_user', 'people/:company_id/users/:user_id', array('controller' => 'users', 'action' => 'view'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_add', 'people/:company_id/add-user', array('controller' => 'users', 'action' => 'add'), array('company_id' => Router::MATCH_ID));
      Router::map('people_company_user_edit', 'people/:company_id/users/:user_id/edit', array('controller' => 'users', 'action' => 'edit'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_edit_profile', 'people/:company_id/users/:user_id/edit-profile', array('controller' => 'users', 'action' => 'edit_profile'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_edit_settings', 'people/:company_id/users/:user_id/edit-settings', array('controller' => 'users', 'action' => 'edit_settings'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_edit_company_and_role', 'people/:company_id/users/:user_id/edit-company-and-role', array('controller' => 'users', 'action' => 'edit_company_and_role'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_export_vcard', 'people/:company_id/users/:user_id/export-vcard', array('controller' => 'users', 'action' => 'export_vcard'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_delete', 'people/:company_id/users/:user_id/delete', array('controller' => 'users', 'action' => 'delete'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_edit_password', 'people/:company_id/users/:user_id/edit-password', array('controller' => 'users', 'action' => 'edit_password'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      
      Router::map('people_company_user_recent_activities', 'people/:company_id/users/:user_id/recent-activities', array('controller' => 'users', 'action' => 'recent_activities'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_send_welcome_message', 'people/:company_id/users/:user_id/send-welcome-message', array('controller' => 'users', 'action' => 'send_welcome_message'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_login_as', 'people/:company_id/users/:user_id/login-as', array('controller' => 'users', 'action' => 'login_as'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      
      // activeCollab specific add to / remove from favorites routes
     	Router::map('people_company_user_favorites', 'people/:company_id/users/:user_id/favorites', array('controller' => 'favorites'), array('user_id' => Router::MATCH_ID), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_add_to_favorites', 'people/:company_id/users/:user_id/favorites/add', array('controller' => 'favorites', 'action' => 'add_to_favorites'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_remove_from_favorites', 'people/:company_id/users/:user_id/favorites/remove', array('controller' => 'favorites', 'action' => 'remove_from_favorites'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      
      AngieApplication::getModule('authentication')->defineApiClientSubscriptionsRoutesFor('people_company_user', 'people/:company_id/users/:user_id', 'users', SYSTEM_MODULE, array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      AngieApplication::getModule('environment')->defineStateRoutesFor('people_company_user', 'people/:company_id/users/:user_id', 'users', SYSTEM_MODULE, array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      AngieApplication::getModule('avatar')->defineAvatarRoutesFor('people_company_user', 'people/:company_id/users/:user_id', 'users', SYSTEM_MODULE, array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      AngieApplication::getModule('homescreens')->defineHomescreenRoutesFor('people_company_user', 'people/:company_id/users/:user_id', 'users', SYSTEM_MODULE, array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      AngieApplication::getModule('reminders')->defineUserRemindersRoutesFor('people_company_user', 'people/:company_id/users/:user_id', 'users', SYSTEM_MODULE, array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      AngieApplication::getModule('activity_logs')->defineActivityLogsRoutesFor('people_company_user', 'people/:company_id/users/:user_id', 'users', SYSTEM_MODULE, array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));

      // User projects
      Router::map('people_company_user_projects', 'people/:company_id/users/:user_id/projects', array('controller' => 'user_projects', 'action' => 'index'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_projects_archive', 'people/:company_id/users/:user_id/projects/archive', array('controller' => 'user_projects', 'action' => 'archive'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      Router::map('people_company_user_add_to_projects', 'people/:company_id/users/:user_id/add-to-projects', array('controller' => 'user_projects', 'action' => 'add_to_projects'), array('company_id' => Router::MATCH_ID, 'user_id' => Router::MATCH_ID));
      
      // Projects
      Router::map('projects', 'projects', array('controller' => 'projects'));
      Router::map('projects_mass_edit', 'projects/multiple/mass-edit', array('controller' => 'projects', 'action' => 'mass_edit'));
      Router::map('project', 'projects/:project_slug', array('controller' => 'project', 'action' => 'index')); // Defined here, so other global /projects actions can override it

      AngieApplication::getModule('complete')->defineChangeStatusRoutesFor('project', 'projects/:project_slug', 'project_complete', SYSTEM_MODULE);
      AngieApplication::getModule('avatar')->defineAvatarRoutesFor('project', 'project/:project_slug', 'project', SYSTEM_MODULE);
      
      Router::map('projects_add', 'projects/add', array('controller' => 'project', 'action' => 'add'));
      Router::map('projects_archive', 'projects/archive', array('controller' => 'projects', 'action' => 'archive'));
      Router::map('project_labels', 'info/labels/project', array('controller' => 'projects', 'action' => 'labels'));
      
      // Project categories
      AngieApplication::getModule('categories')->defineCategoriesRoutesFor('project', 'projects', 'projects', SYSTEM_MODULE);
      AngieApplication::getModule('categories')->defineCategoryRoutesFor('project', 'projects/:project_slug', 'project', SYSTEM_MODULE);
      AngieApplication::getModule('environment')->defineStateRoutesFor('project', 'projects/:project_slug', 'project', SYSTEM_MODULE);
      AngieApplication::getModule('complete')->defineChangeStatusRoutesFor('project', 'projects/:project_slug', 'project', SYSTEM_MODULE);
      AngieApplication::getModule('labels')->defineLabelsRoutesFor('project', 'projects/:project_slug', 'project', SYSTEM_MODULE);
      
      // Project tracking
      if(AngieApplication::isModuleLoaded('tracking')) {
        AngieApplication::getModule('tracking')->defineTrackingRoutesFor('project', 'projects/:project_slug', 'project', SYSTEM_MODULE);
      } // if
      
      // Invoicing
      if(AngieApplication::isModuleLoaded('invoicing')) {
        AngieApplication::getModule('invoicing')->defineInvoiceRoutesFor('project', 'project/:project_slug', 'project', SYSTEM_MODULE, array('project_slug' => Router::MATCH_SLUG));
        AngieApplication::getModule('invoicing')->defineInvoiceRoutesFor('project_milestone', 'milestone', 'milestones', SYSTEM_MODULE);
      } // if
      
      // Single project
      Router::map('project_user_tasks', 'projects/:project_slug/user-tasks', array('controller' => 'project', 'action' => 'user_tasks'));
      Router::map('project_user_subscriptions', 'projects/:project_slug/user-subscriptions', array('controller' => 'project', 'action' => 'user_subscriptions'));
      Router::map('project_user_subscriptions_mass_unsubscribe', 'projects/:project_slug/user-subscriptions-mass-unsubscribe', array('controller' => 'project', 'action' => 'user_subscriptions_mass_unsubscribe'));
      Router::map('project_ical', 'projects/:project_slug/ical', array('controller' => 'project', 'action' => 'ical'));
      Router::map('project_ical_subscribe', 'projects/:project_slug/ical-subscribe', array('controller' => 'project', 'action' => 'ical_subscribe'));
      Router::map('project_edit', 'projects/:project_slug/edit', array('controller' => 'project', 'action' => 'edit'));

      AngieApplication::getModule('activity_logs')->defineActivityLogsRoutesFor('project', 'projects/:project_slug', 'project', SYSTEM_MODULE);
      
      Router::map('project_delete', 'projects/:project_slug/delete', array('controller' => 'project', 'action' => 'delete'));
      Router::map('project_pin', 'projects/:project_slug/pin', array('controller' => 'project', 'action' => 'pin'));
      Router::map('project_unpin', 'projects/:project_slug/unpin', array('controller' => 'project', 'action' => 'unpin'));
      Router::map('project_export', 'projects/:project_slug/export', array('controller' => 'project', 'action' => 'export'));
      
      Router::map('project_edit_icon', 'projects/:project_slug/icon/edit', array('controller' => 'project_icon', 'action' => 'edit'));
      Router::map('project_delete_icon', 'projects/:project_slug/icon/delete', array('controller' => 'project_icon', 'action' => 'delete'));
      
      Router::map('project_settings', 'projects/:project_slug/settings', array('controller' => 'project', 'action' => 'settings'));
      Router::map('project_additional_step', 'projects/:project_slug/additiona-steps/:step', array('controller' => 'project', 'action' => 'additional_step'));
      
      // Project people
      Router::map('project_people', 'projects/:project_slug/people', array('controller' => 'project_people', 'action' => 'index'));
      Router::map('project_people_add', 'projects/:project_slug/people/add', array('controller' => 'project_people', 'action' => 'add_people'));
      Router::map('project_replace_user', 'projects/:project_slug/people/:user_id/replace', array('controller' => 'project_people', 'action' => 'replace_user'), array('user_id' => Router::MATCH_ID));
      Router::map('project_remove_user', 'projects/:project_slug/people/:user_id/remove-from-project', array('controller' => 'project_people', 'action' => 'remove_user'), array('user_id' => Router::MATCH_ID));
      Router::map('project_user_permissions', 'projects/:project_slug/people/:user_id/change-permissions', array('controller' => 'project_people', 'action' => 'user_permissions'), array('user_id' => Router::MATCH_ID));
      
      // Project milestones
      Router::map('project_milestones', 'projects/:project_slug/milestones', array('controller' => 'milestones', 'action' => 'index'));
      Router::map('project_milestones_archive', 'projects/:project_slug/milestones/archive', array('controller' => 'milestones', 'action' => 'archive'));
      Router::map('project_milestones_add', 'projects/:project_slug/milestones/add', array('controller' => 'milestones', 'action' => 'add'));
      Router::map('project_milestones_export', 'projects/:project_slug/milestones/export', array('controller' => 'milestones', 'action' => 'export'));
      
      Router::map('project_milestone', 'projects/:project_slug/milestones/:milestone_id', array('controller' => 'milestones', 'action' => 'view'), array('milestone_id' => Router::MATCH_ID));
      Router::map('project_milestone_edit', 'projects/:project_slug/milestones/:milestone_id/edit', array('controller' => 'milestones', 'action' => 'edit'), array('milestone_id' => Router::MATCH_ID));
      Router::map('project_milestone_comments', 'projects/:project_slug/milestones/:milestone_id/comments', array('controller' => 'milestones', 'action' => 'comments'), array('milestone_id' => Router::MATCH_ID));
      
      AngieApplication::getModule('complete')->defineChangeStatusRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      AngieApplication::getModule('complete')->definePriorityRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      AngieApplication::getModule('environment')->defineStateRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      AngieApplication::getModule('comments')->defineCommentsRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      AngieApplication::getModule('subscriptions')->defineSubscriptionRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      AngieApplication::getModule('reminders')->defineRemindersRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      AngieApplication::getModule('assignees')->defineAssigneesRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      AngieApplication::getModule('attachments')->defineAttachmentsRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      
      // Project outline
      Router::map('project_outline', 'projects/:project_slug/outline', array('controller' => 'project_outline', 'action' => 'index'));
      Router::map('project_outline_shortcuts', 'projects/:project_slug/outline/shortcuts', array('controller' => 'project_outline', 'action' => 'shortcuts'));
      Router::map('project_outline_subobjects', 'projects/:project_slug/outline/:object_type/:object_id/subobjects', array('controller' => 'project_outline', 'action' => 'subobjects'));
      Router::map('project_outline_reorder', 'projects/:project_slug/outline/:object_type/:object_id/reorder', array('controller' => 'project_outline', 'action' => 'reorder'));
      Router::map('project_outline_mass_edit', 'projects/:project_slug/outline/mass_edit', array('controller' => 'project_outline', 'action' => 'mass_edit', array('parent_id' => Router::MATCH_ID, 'subtask_id' => Router::MATCH_ID)));
      
      // Project objects (generic, this stuff is usually overriden)
      Router::map('project_objects', 'projects/:project_slug/objects', array('controller' => 'projects', 'action' => 'overview'));
      Router::map('project_object_move', 'projects/:project_slug/objects/:object_id/move', array('controller' => 'project_objects', 'action' => 'move'), array('object_id' => Router::MATCH_ID));
      Router::map('project_object_copy', 'projects/:project_slug/objects/:object_id/copy', array('controller' => 'project_objects', 'action' => 'copy'), array('object_id' => Router::MATCH_ID));
      Router::map('project_object_update_milestone', 'projects/:project_slug/objects/:object_id/update-milestone', array('controller' => 'milestones', 'action' => 'update_milestone'), array('object_id' => Router::MATCH_ID));
      
      // Reports
      Router::map('milestone_filters', 'reports/milestones', array('controller' => 'milestone_filters'));
      Router::map('milestone_filters_run', 'reports/milestones/run', array('controller' => 'milestone_filters', 'action' => 'run'));
      Router::map('milestone_filters_export', 'reports/milestones/export', array('controller' => 'milestone_filters', 'action' => 'export'));
      Router::map('milestone_filters_add', 'reports/milestones/add', array('controller' => 'milestone_filters', 'action' => 'add'));

      Router::map('assignment_filter', 'reports/milestones/:assignment_filter_id', array('controller' => 'milestone_filters', 'action' => 'view'), array('assignment_filter_id' => Router::MATCH_ID));
      Router::map('assignment_filter_edit', 'reports/milestones/:assignment_filter_id/edit', array('controller' => 'milestone_filters', 'action' => 'edit'), array('assignment_filter_id' => Router::MATCH_ID));
      Router::map('assignment_filter_delete', 'reports/milestones/:assignment_filter_id/delete', array('controller' => 'milestone_filters', 'action' => 'delete'), array('assignment_filter_id' => Router::MATCH_ID));

      // Assignment filters
      Router::map('assignment_filters', 'reports/assignments', array('controller' => 'assignment_filters'));
      Router::map('assignment_filters_run', 'reports/assignments/run', array('controller' => 'assignment_filters', 'action' => 'run'));
      Router::map('assignment_filters_export', 'reports/assignments/export', array('controller' => 'assignment_filters', 'action' => 'export'));
      Router::map('assignment_filters_add', 'reports/assignments/add', array('controller' => 'assignment_filters', 'action' => 'add'));
      
      Router::map('assignment_filter', 'reports/assignments/:assignment_filter_id', array('controller' => 'assignment_filters', 'action' => 'view'), array('assignment_filter_id' => Router::MATCH_ID));
      Router::map('assignment_filter_edit', 'reports/assignments/:assignment_filter_id/edit', array('controller' => 'assignment_filters', 'action' => 'edit'), array('assignment_filter_id' => Router::MATCH_ID));
      Router::map('assignment_filter_delete', 'reports/assignments/:assignment_filter_id/delete', array('controller' => 'assignment_filters', 'action' => 'delete'), array('assignment_filter_id' => Router::MATCH_ID));
      
      // Project requests
      Router::map('project_requests', 'projects/requests', array('controller' => 'project_requests'));
      Router::map('project_requests_archive', 'projects/requests/archive', array('controller' => 'project_requests', 'action' => 'archive'));
      Router::map('project_requests_mass_edit', 'projects/requests/mass-edit', array('controller' => 'project_requests', 'action' => 'mass_edit'));
      Router::map('project_requests_add', 'projects/requests/add', array('controller' => 'project_requests', 'action' => 'add'));
      
      Router::map('project_request', 'projects/requests/:project_request_id', array('controller' => 'project_requests', 'action' => 'view'), array('project_request_id' => Router::MATCH_ID));
      Router::map('project_request_edit', 'projects/requests/:project_request_id/edit', array('controller' => 'project_requests', 'action' => 'edit'), array('project_request_id' => Router::MATCH_ID));
      Router::map('project_request_open', 'projects/requests/:project_request_id/open', array('controller' => 'project_requests', 'action' => 'open'), array('project_request_id' => Router::MATCH_ID));
      Router::map('project_request_close', 'projects/requests/:project_request_id/close', array('controller' => 'project_requests', 'action' => 'close'), array('project_request_id' => Router::MATCH_ID));
      Router::map('project_request_take', 'projects/requests/:project_request_id/take', array('controller' => 'project_requests', 'action' => 'take'), array('project_request_id' => Router::MATCH_ID));
      Router::map('project_request_create_project', 'projects/requests/:project_request_id/create-project', array('controller' => 'project_requests', 'action' => 'create_project'), array('project_request_id' => Router::MATCH_ID));
      Router::map('project_request_create_quote', 'projects/requests/:project_request_id/create-quote', array('controller' => 'project_requests', 'action' => 'create_quote'), array('project_request_id' => Router::MATCH_ID));
      Router::map('project_request_delete', 'projects/requests/:project_request_id/delete', array('controller' => 'project_requests', 'action' => 'delete'), array('project_request_id' => Router::MATCH_ID));
      Router::map('project_request_save_client', 'projects/requests/:project_request_id/save-client', array('controller' => 'project_requests', 'action' => 'save_client'), array('project_request_id' => Router::MATCH_ID));

      AngieApplication::getModule('attachments')->defineAttachmentsRoutesFor('project_request', 'project-requests/:project_request_id', 'project_requests', SYSTEM_MODULE, array('project_request_id' => Router::MATCH_ID));
      
      // Comments
      AngieApplication::getModule('comments')->defineCommentsRoutesFor('project_request', 'project-requests/:project_request_id', 'project_requests', SYSTEM_MODULE, array('project_request_id' => Router::MATCH_ID));
      
      // Subscriptions
      AngieApplication::getModule('subscriptions')->defineSubscriptionRoutesFor('project_request', 'project-requests/:project_request_id', 'project_requests', SYSTEM_MODULE, array('project_request_id' => Router::MATCH_ID));
      
      // Public part of project requests
      Router::map('project_request_submit', 'project-requests/submit', array('controller' => 'project_requests_public', 'action' => 'index'));
      Router::map('project_request_check', 'project-requests/check/:project_request_public_id', array('controller' => 'project_requests_public', 'action' => 'view'), array('project_request_public_id' => Router::MATCH_WORD));
      
      // Shared object
      Router::map('shared_object', 's/:sharing_context/:sharing_code', array('controller' => 'frontend', 'action' => 'default_view_shared_object'), array('sharing_code' => Router::MATCH_WORD));

			$this->defineScheduleRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
			$this->defineMoveToProjectRoutesFor('project_milestone', 'projects/:project_slug/milestones/:milestone_id', 'milestones', SYSTEM_MODULE, array('milestone_id' => Router::MATCH_ID));
      
      // ---------------------------------------------------
      //  Administration
      // ---------------------------------------------------
      
      // Project roles
      Router::map('admin_project_roles', 'admin/roles/project', array('controller' => 'project_roles_admin', 'action' => 'index'));
      Router::map('admin_project_roles_add', 'admin/roles/project/add', array('controller' => 'project_roles_admin', 'action' => 'add'));
      
      Router::map('admin_project_role', 'admin/roles/project/:role_id', array('controller' => 'project_roles_admin', 'action' => 'view'), array('role_id' => Router::MATCH_ID));
      Router::map('admin_project_role_edit', 'admin/roles/project/:role_id/edit', array('controller' => 'project_roles_admin', 'action' => 'edit'), array('role_id' => Router::MATCH_ID));
      Router::map('admin_project_role_delete', 'admin/roles/project/:role_id/delete', array('controller' => 'project_roles_admin', 'action' => 'delete'), array('role_id' => Router::MATCH_ID));
      Router::map('admin_project_role_set_as_default', 'admin/roles/project/:role_id/set-as-default', array('controller' => 'project_roles_admin', 'action' => 'set_as_default'), array('role_id' => Router::MATCH_ID));
      
      // Project labels
      LabelsFramework::defineLabelsAdminRoutesFor('projects_admin', 'admin/project-labels', 'project_labels_admin', SYSTEM_MODULE);
      
      // Settings
      Router::map('admin_settings', 'admin', array('controller' => 'admin'));
      Router::map('admin_settings_general', 'admin/settings/general', array('controller' => 'settings', 'action' => 'general'));
      Router::map('admin_settings_categories', 'admin/settings/categories', array('controller' => 'categories_admin'));
      
      Router::map('identity_admin', 'admin/identity', array('controller' => 'identity_admin'));
      
      // Projects
      Router::map('admin_projects', 'admin/projects', array('controller' => 'projects_admin'));
      
      // Project requests
      Router::map('admin_project_requests', 'admin/project-requests', array('controller' => 'project_requests_admin'));
      
      // Search index
      Router::map('projects_search_index_admin_build', 'admin/search/projects/build', array('controller' => 'projects_search_index_admin', 'action' => 'build', 'search_index_name' => 'projects'));
      Router::map('project_objects_search_index_admin_build', 'admin/search/project-objects/build', array('controller' => 'project_objects_search_index_admin', 'action' => 'build', 'search_index_name' => 'project_objects'));
      Router::map('names_search_index_admin_build', 'admin/search/names/build/:action', array('controller' => 'names_search_index_admin', 'search_index_name' => 'names'));
      
      // Activity
      Router::map('activity_logs_admin_rebuild_people', 'admin/indices/activity-logs/rebuild/people', array('controller' => 'activity_logs_admin', 'action' => 'rebuild_people'));
      Router::map('activity_logs_admin_rebuild_projects', 'admin/indices/activity-logs/rebuild/projects', array('controller' => 'activity_logs_admin', 'action' => 'rebuild_projects'));
      Router::map('activity_logs_admin_rebuild_milestones', 'admin/indices/activity-logs/rebuild/milestones', array('controller' => 'activity_logs_admin', 'action' => 'rebuild_milestones'));
      
      Router::map('object_contexts_admin_rebuild_people', 'admin/indices/object-contexts/rebuild/people', array('controller' => 'object_contexts_admin', 'action' => 'rebuild_people'));
      Router::map('object_contexts_admin_rebuild_projects', 'admin/indices/object-contexts/rebuild/projects', array('controller' => 'object_contexts_admin', 'action' => 'rebuild_projects'));
      Router::map('object_contexts_admin_rebuild_milestones', 'admin/indices/object-contexts/rebuild/milestones', array('controller' => 'object_contexts_admin', 'action' => 'rebuild_milestones'));
    
       // Incoming mail actions
      Router::map('project_action_project_changed', 'project_action/project_changed', array('controller' => 'project_action', 'action' => 'project_change'), array('project_id' => Router::MATCH_ID));
    } // defineRoutes
    
    /**
     * Define sharing routes for given context
     *
     * @param string $context
     * @param string $context_path
     * @param array $context_defaults
     * @param array $context_requirements
     */                            
    function defineSharingRoutesFor($context, $context_path, $controller_name, $module_name, $context_requirements = null) {
      Router::map("{$context}_sharing_settings", "$context_path/sharing", array('controller' => $controller_name, 'action' => "{$context}_sharing_settings", 'module' => $module_name), $context_requirements);
    } // defineSharingRoutesFor
    
    /**
     * Define schedule routes for given context
     *
     * @param string $context
     * @param string $context_path
     * @param array $context_defaults
     * @param array $context_requirements
     */
    function defineScheduleRoutesFor($context, $context_path, $controller_name, $module_name, $context_requirements = null) {
      Router::map("{$context}_reschedule", "$context_path/reschedule", array('controller' => $controller_name, 'action' => "{$context}_reschedule", 'module' => $module_name), $context_requirements);
    } // defineScheduleRoutesFor
    
    /**
     * Define schedule routes for given context
     *
     * @param string $context
     * @param string $context_path
     * @param array $context_defaults
     * @param array $context_requirements
     */
    function defineMoveToProjectRoutesFor($context, $context_path, $controller_name, $module_name, $context_requirements = null) {
      Router::map("{$context}_move_to_project", "$context_path/move-to-project", array('controller' => $controller_name, 'action' => "{$context}_move_to_project", 'module' => $module_name), $context_requirements);
      Router::map("{$context}_copy_to_project", "$context_path/copy-to-project", array('controller' => $controller_name, 'action' => "{$context}_copy_to_project", 'module' => $module_name), $context_requirements);
    } // defineMoveToProjectRoutesFor
    
    /**
     * Define event handlers
     */
    function defineHandlers() {
      EventsManager::listen('on_visible_contexts', 'on_visible_contexts');
      
      EventsManager::listen('on_homescreen_tab_types', 'on_homescreen_tab_types');
      EventsManager::listen('on_homescreen_widget_types', 'on_homescreen_widget_types');
      
      EventsManager::listen('on_daily', 'on_daily');

      EventsManager::listen('on_project_export', 'on_project_export');
      EventsManager::listen('on_project_overview_sidebars', 'on_project_overview_sidebars');
      EventsManager::listen('on_projects_tabs', 'on_projects_tabs');
      EventsManager::listen('on_available_project_tabs', 'on_available_project_tabs');
      EventsManager::listen('on_project_brief_stats', 'on_project_brief_stats');
      
			EventsManager::listen('on_inline_tabs', 'on_inline_tabs');
      
      EventsManager::listen('on_settings_sections', 'on_settings_sections');
      EventsManager::listen('on_admin_panel', 'on_admin_panel');
      
      EventsManager::listen('on_system_permissions', 'on_system_permissions');
      
      EventsManager::listen('on_label_types', 'on_label_types');
      
      EventsManager::listen('on_user_cleanup', 'on_user_cleanup');
      
      EventsManager::listen(array(
        'on_get_completable_project_object_types', 
        'on_get_day_project_object_types', 
      ), 'register_milestone_type');
      
      EventsManager::listen('on_project_permissions', 'on_project_permissions');
      EventsManager::listen('on_object_inspector', 'on_object_inspector');
      EventsManager::listen('on_notification_inspector', 'on_notification_inspector');
            
      EventsManager::listen('on_quick_add', 'on_quick_add');
      EventsManager::listen('on_search_indices', 'on_search_indices');
      
      EventsManager::listen('on_rebuild_activity_log_actions', 'on_rebuild_activity_log_actions');
      EventsManager::listen('on_rebuild_object_contexts_actions', 'on_rebuild_object_contexts_actions');

      EventsManager::listen('on_notification_context_view_url', 'on_notification_context_view_url');
      EventsManager::listen('on_object_from_notification_context', 'on_object_from_notification_context');

      // update objects that have anonymous client saved to People section
      EventsManager::listen('on_client_saved', 'on_client_saved');

      // Drop project progress cache
      // 
      // - state changes drop cache complete
      // - copy and move between projects clear cache on project object class 
      //   level, so no need for external cache clearning is needed
      EventsManager::listen(array(
        'on_object_inserted', 
        'on_object_completed', 
        'on_object_opened', 
      ), 'drop_project_progress_cache');
    } // defineHandlers
    
    // ---------------------------------------------------
    //  Names
    // ---------------------------------------------------
    
    /**
     * Get module display name
     *
     * @return string
     */
    function getDisplayName() {
      return lang('System');
    } // getDisplayName
    
    /**
     * Return module description
     *
     * @return string
     */
    function getDescription() {
      return lang('activeCollab foundation');
    } // getDescription
    
  }