<?php
class EventsController extends AppController 
{
    public $name = 'Events';
    public $uses = array('Event', 'EventComment', 'EventAttendee', 'User', 'Profile');
    public $components = array('RequestHandler', 'Activity', 'Notification');
    
    public function beforeFilter() 
    {
        parent::beforeFilter();
    }
    
    public function isAuthorized($user) 
    {
        //If member hasn't filled in profile redirect to Edit Profile
        if (!$this->User->access($this->Auth->user('id'))) {
            $this->Session->setFlash(__('You must first complete your profile.'), 
                'default', array('class' => 'alert alert-danger'));
            return $this->redirect(array('controller' => 'users', 'action' => 'edit', $this->Auth->user('id')));
        }
        
        //All members have access to these actions
        if (in_array($this->action, array('index', 'json_index', 'add', 'calendar'))) {
            return true;
        }
        
        //If item is for administrators only, only administrators have access to these actions. 
        //Else all members have access to these actions
        if (in_array($this->action, array('view', 'attendees', 'attend'))) {
            $itemId = (int) $this->request->params['pass'][0];
            if ($this->Auth->user('role') == 'user') {
                $conditions = array(
                    'Event.id' => $itemId,
                    'Event.admin' => '0',
                    'Event.deleted' => 0
                ); 
            } else {
                $conditions = array(
                    'Event.id' => $itemId,
                    'Event.deleted' => 0
                ); 
            }
            $item = $this->Event->find('first', array(
                'conditions' => $conditions
            ));
            if (!empty($item)) {
                return true;
            }
        }
        
        //All members have access to these actions if the item is their own
        if (in_array($this->action, array('edit', 'delete'))) {
            $itemId = (int) $this->request->params['pass'][0];
            if ($this->Event->isOwnedBy($itemId, $user['id'])) {
                return true;
            }
        }
        
        if ($this->action === 'comment') {
            //All members have access to this action if the comment is their own
            if (!empty($this->request->data['EventComment']['id'])) {
                // Update comment
                $itemId = (int) $this->request->data['EventComment']['id'];
                if ($this->EventComment->isOwnedBy($itemId, $user['id'])) {
                    return true;
                }
            } else {
                //All members have access to this action
                return true;
            }
        }
        
        //All members have access to these actions if the comment is their own
        if ($this->action === 'comment_delete') {
            $itemId = (int) $this->request->params['pass'][0];
            if ($this->EventComment->isOwnedBy($itemId, $user['id'])) {
                return true;
            }
        }
    
        return parent::isAuthorized($user);
    }

    public function index() 
    {
        $this->Event->Behaviors->load('Containable');
        
        //Get all events based on member role (administrator/user)
        if ($this->Auth->user('role') == 'user') {
            $conditions = array(
                'Event.admin' => '0',
                'Event.deleted' => 0
            ); 
        } else {
            $conditions = array(
                'Event.deleted' => 0
            );
        }
        if (Configure::read('CFG.users_follow')) {
            $user = $this->User->find('first', array(
                    'conditions' => array('User.id' => $this->Auth->user('id'), 'User.deleted' => 0),
                )
            );            
            $user_id = $user['UserFollow'];
            $user_id[] = $this->Auth->user('id');
            
            $conditions['AND'] = array(
                'Event.user_id' => $user_id,
            );
        }
        $items = $this->Event->find('all', array(
            'conditions' => $conditions,
            'order' => array('Event.created DESC'),
            'contain' => array(
                'User' => array(
                    'Profile',
                ),
                'EventComment'
            ),
            'recursive' => 1
            )
        );
        
        $this->set('items', $items);
        $this->set('title_for_layout', __('Calendar'));
    }
    
    //Get items for fullcalendar
    public function json_index() 
    {
        $this->layout = false;
        $this->Event->Behaviors->load('Containable');
        
        //Get all events based on member role (administrator/user)
        if ($this->Auth->user('role') == 'user') {
            $conditions = array(
                'Event.admin' => '0',
                'Event.deleted' => 0
            ); 
        } else {
            $conditions = array(
                'Event.deleted' => 0
            ); 
        }
        if (Configure::read('CFG.users_follow')) {
            $user = $this->User->find('first', array(
                    'conditions' => array('User.id' => $this->Auth->user('id'), 'User.deleted' => 0),
                )
            );            
            $user_id = $user['UserFollow'];
            $user_id[] = $this->Auth->user('id');
            
            $conditions['AND'] = array(
                'Event.user_id' => $user_id,
            );
        }
        $items = $this->Event->find('all', array(
            'conditions' => $conditions,
            'order' => array('Event.created DESC'),
            'contain' => array(
                'User' => array(
                    'Profile',
                ),
                'EventComment'
            ),
            'recursive' => 1
            )
        );
        
        //Generate array for json
        App::uses('CakeTime', 'Utility');
        $array = array();
        foreach ($items as $item) {
            $array[] = array(
                'id' =>  $item['Event']['id'],
                'title' => $item['Event']['title'],
                'start' => CakeTime::format('Y-m-d H:i', $item['Event']['start_date'] . ' ' . $item['Event']['start_time'], null, Configure::read('CFG.timezone')),
                'end' => CakeTime::format('Y-m-d H:i', $item['Event']['end_date'] . ' ' . $item['Event']['end_date'], null, Configure::read('CFG.timezone')),
                'allDay' => false
            );
        }
        
        $this->set('json', $array);
        $this->render('../Elements/json');
    }
    
    public function view($id = null) 
    {
        if (empty($id)) {
            return $this->redirect(array('action' => 'index'));
        }
        
        // Get item
        $this->Event->Behaviors->load('Containable');
        $item = $this->Event->find('first', array(
                'conditions' => array('Event.id' => $id, 'Event.deleted' => 0),
                'contain' => array(
                    'User' => array(
                        'Profile',
                    ),
                    'EventComment' => array(
                        'User' => array(
                            'Profile',
                        ),
                    ),
                    'EventAttendee' => array(
                        'conditions' => array('EventAttendee.user_id' => $this->Auth->user('id')),
                    ),
                ),
            )
        );
        if (!$item) {
            return $this->redirect(array('action' => 'index'));
        }
        $this->set('item', $item);
        $this->set('title_for_layout', $item['Event']['title']);
    }
    
    //Get all attendees for an event based on status (present/absent)
    public function attendees($id = null, $status = null) 
    {
        $this->layout = false;
        if (empty($id)) {
            return false;
        }
        if (empty($status)) {
            return false;
        }
        
        $this->Event->Behaviors->load('Containable');
        $item = $this->Event->find('first', array(
                'conditions' => array('Event.id' => $id, 'Event.deleted' => 0),
                'contain' => array(
                    'EventAttendee' => array(
                        'conditions' => array('EventAttendee.status' => $status),
                        'User' => array(
                            'Profile',
                        ),
                    ),
                ),
            )
        );
        
        $this->set('json', $item['EventAttendee']);
        $this->render('../Elements/json');
    }
    
    //Update attendance for member for an event (present/absent)
    public function attend($id = null, $status = null) 
    {
        $this->layout = false;
        $this->autoRender = false;
        if (empty($id)) {
            return false;
        }
        if (empty($status)) {
            return false;
        }
        
        $item = $this->EventAttendee->find('first', array(
                'conditions' => array('EventAttendee.event_id' => $id, 'EventAttendee.user_id' => $this->Auth->user('id')),
            )
        );
        //If member has not yet responded to attendance create; Else update
        if (!empty($item)) {
            if ($item['EventAttendee']['status'] == $status) {
                if ($this->EventAttendee->delete($item['EventAttendee']['id'])) {
                    $this->Activity->log($this->EventAttendee->id, 'EventAttendee', 'delete');
                    return 3;
                }
            } else {
                $item['EventAttendee']['status'] = $status;
                if ($this->EventAttendee->save($item)) {
                    $this->Activity->log($this->EventAttendee->id, 'EventAttendee', $status);
                    return 2;
                }
            }
        } else {
            $item['EventAttendee']['event_id'] = $id;
            $item['EventAttendee']['user_id'] = $this->Auth->user('id');
            $item['EventAttendee']['status'] = $status;
            if ($this->EventAttendee->save($item)) {
                $this->Activity->log($this->EventAttendee->id, 'EventAttendee', $status);
                return 1;
            }
        }
        
        return false;
    }
    
    public function add() 
    {
        //If data submitted save data
        if ($this->request->is('post')) {
            $this->request->data['Event']['user_id'] = $this->Auth->user('id');
            if ((isset($this->request->data['Event']['admin'])) && ($this->Auth->user('role') == 'user')) {
                //security check
                $this->request->data['Event']['admin'] = 0;
            }
            
            $session = $this->Session->read('Auth');
            
            $this->request->data['Event']['start_date'] = $this->convert_date($this->request->data['Event']['start_date']);
            $start = new DateTime($this->request->data['Event']['start_date'] . ' ' . $this->request->data['Event']['start_time'], 
                new DateTimeZone($session['UserSetting']['timezone']));
            $start->setTimeZone(new DateTimeZone('UTC'));
            $this->request->data['Event']['start_date'] = $start->format('Y-m-d');
            $this->request->data['Event']['start_time'] = $start->format('H:i:s');
            
            $this->request->data['Event']['end_date'] = $this->convert_date($this->request->data['Event']['end_date']);
            $end = new DateTime($this->request->data['Event']['end_date'] . ' ' . $this->request->data['Event']['end_time'], 
                new DateTimeZone($session['UserSetting']['timezone']));
            $end->setTimeZone(new DateTimeZone('UTC'));
            $this->request->data['Event']['end_date'] = $end->format('Y-m-d');
            $this->request->data['Event']['end_time'] = $end->format('H:i:s');
            
            if ($this->Event->save($this->request->data)) {
                $this->Activity->log($this->Event->id, 'Event', 'add');
                
                // Notification
                if (isset($this->request->data['Event']['notify']) && $this->request->data['Event']['notify']) {           
                    $view_vars = array(
                        'title' => $this->request->data['Event']['title'],
                        'url' => Configure::read('CFG.site_url') . '/events/view/' . $this->Event->id,
                    );
                    $this->Notification->push(
                        'item_add',
                        null,
                        $view_vars,
                        (isset($this->request->data['Event']['admin']) ? true : false)
                    );
                }
            
                $this->Session->setFlash(__('Event successfully saved'), 'default', array('class' => 'alert alert-success'));
                return $this->redirect(array('action' => 'index'));
            }
            $this->Session->setFlash(__('An error has occurred'), 'default', array('class' => 'alert alert-danger'));
        }
        $this->set('title_for_layout', __('Add Event'));
    }
    
    public function edit($id = null) 
    {
        if (empty($id)) {
            return $this->redirect(array('action' => 'index'));
        }
        
        //If data submitted save data
        if ($this->request->is('post')) {
            $this->request->data['Event']['id'] = $id;
            if ((isset($this->request->data['Event']['admin'])) && ($this->Auth->user('role') == 'user')) {
                //security check
                $this->request->data['Event']['admin'] = 0;
            }
            
            $session = $this->Session->read('Auth');
            
            $this->request->data['Event']['start_date'] = $this->convert_date($this->request->data['Event']['start_date']);
            $start = new DateTime($this->request->data['Event']['start_date'] . ' ' . $this->request->data['Event']['start_time'], 
                new DateTimeZone($session['UserSetting']['timezone']));
            $start->setTimeZone(new DateTimeZone('UTC'));
            $this->request->data['Event']['start_date'] = $start->format('Y-m-d');
            $this->request->data['Event']['start_time'] = $start->format('H:i:s');
            
            $this->request->data['Event']['end_date'] = $this->convert_date($this->request->data['Event']['end_date']);
            $end = new DateTime($this->request->data['Event']['end_date'] . ' ' . $this->request->data['Event']['end_time'], 
                new DateTimeZone($session['UserSetting']['timezone']));
            $end->setTimeZone(new DateTimeZone('UTC'));
            $this->request->data['Event']['end_date'] = $end->format('Y-m-d');
            $this->request->data['Event']['end_time'] = $end->format('H:i:s');
            
            if ($this->Event->save($this->request->data)) {
                $this->Activity->log($this->Event->id, 'Event', 'edit');
                
                $this->Session->setFlash(__('Event successfully saved'), 'default', array('class' => 'alert alert-success'));
                return $this->redirect(array('action' => 'view', $id));
            }
            $this->Session->setFlash(__('An error has occurred'), 'default', array('class' => 'alert alert-danger'));
            return $this->redirect(array('action' => 'index'));
        }
        
        //Find event to edit
        $this->Event->Behaviors->load('Containable');
        $item = $this->Event->find('first', array(
                'conditions' => array('Event.id' => $id, 'Event.deleted' => 0),
                'contain' => array(
                    'User' => array(
                        'Profile',
                    ),
                    'EventComment' => array(
                        'User' => array(
                            'Profile',
                        ),
                    ),
                ),
            )
        );
        $this->set('item', $item);
        $this->set('title_for_layout', __('Edit Event'));
    }
    
    public function delete($id = null) 
    {
        $this->layout = false;
        $this->render = false;
        
        //Check if item exists; Else redirect to index
        if (!$id) {
            return $this->redirect(array('action' => 'index'));
        }
        $item = $this->Event->find('first', array(
                'conditions' => array('Event.id' => $id, 'Event.deleted' => 0),
            )
        );
        if (!$item) {
            return $this->redirect(array('action' => 'index'));
        }
        
        //Set deleted field to 1 for event
        $this->request->data['Event']['id'] = $id;
        $this->request->data['Event']['deleted'] = 1;
        if ($this->Event->save($this->request->data)) {
            $this->Activity->log($this->Event->id, 'Event', 'delete');
            
            $this->Session->setFlash(__('Event successfully deleted'), 'default', array('class' => 'alert alert-success'));
            return $this->redirect(array('action' => 'index'));
        }
        $this->Session->setFlash(__('An error has occurred'), 'default', array('class' => 'alert alert-danger'));
        return $this->redirect(array('action' => 'index'));
    }
    
    public function comment($id = null) 
    {
        $this->layout = false;
        $this->render = false;
        
        if (empty($id)) {
            return $this->redirect(array('action' => 'index'));
        }
        
        //If data submitted save data
        if ($this->request->is('post')) {
            if (!empty($this->request->data['EventComment']['id'])) {
                // Update comment
                $action = 'edit';
                $item_comment = $this->EventComment->find('first', array(
                        'conditions' => array(
                            'EventComment.id' => $this->request->data['EventComment']['id'], 
                            'EventComment.deleted' => 0
                        ),
                    )
                );
                if ((empty($item_comment)) || ($this->Auth->user('role') != 'admin')) {
                    // Comment is not created by logged in user and logged in user is not an admin => abort
                    return $this->redirect(array('action' => 'index'));
                }
            } else {
                // Add comment
                $action = 'add';
                $this->request->data['EventComment']['event_id'] = $id;
                $this->request->data['EventComment']['user_id'] = $this->Auth->user('id');
            }
            if ($this->EventComment->save($this->request->data)) {
                $this->Activity->log($this->EventComment->id, 'EventComment', $action);
                
                $this->Session->setFlash(__('Comment successfully saved'), 
                    'default', array('class' => 'alert alert-success'));
                return $this->redirect(array('action' => 'view', $id));
            }
            
        }
        $this->Session->setFlash(__('An error has occurred'), 
            'default', array('class' => 'alert alert-danger'));
        return $this->redirect(array('action' => 'index'));
    }
    
    public function comment_delete($id = null) 
    {
        $this->layout = false;
        $this->render = false;
        
        //Check if comment exists; Else redirect to index
        if (!$id) {
            return $this->redirect(array('action' => 'index'));
        }
        $item_comment = $this->EventComment->find('first', array(
                'conditions' => array('EventComment.id' => $id)
            )
        );
        if (!$item_comment) {
            return $this->redirect(array('action' => 'index'));
        }
        
        //Set deleted field to 1 for comment
        $this->request->data['EventComment']['id'] = $id;
        $this->request->data['EventComment']['deleted'] = 1;
        if ($this->EventComment->save($this->request->data)) {
            $this->Activity->log($this->EventComment->id, 'EventComment', 'delete');
            
            $this->Session->setFlash(__('Comment successfully deleted'), 
                'default', array('class' => 'alert alert-success'));
            return $this->redirect(array('action' => 'view', $item_comment['EventComment']['event_id']));
        }
        $this->Session->setFlash(__('An error has occurred'), 
            'default', array('class' => 'alert alert-danger'));
        return $this->redirect(array('action' => 'index'));
    }
    
    public function calendar($id = null) 
    {
        if (empty($id)) {
            return false;
        }
        
        $this->Event->Behaviors->load('Containable');
        $item = $this->Event->find('first', array(
                'conditions' => array('Event.id' => $id, 'Event.deleted' => 0),
                'contain' => array(
                    'User' => array(
                        'Profile',
                    ),
                    'EventComment' => array(
                        'User' => array(
                            'Profile',
                        ),
                    ),
                    'EventAttendee' => array(
                        'conditions' => array('EventAttendee.user_id' => $this->Auth->user('id')),
                    ),
                ),
            )
        );
        $this->set('item', $item);
    }
    
    private function convert_date($date) {
        $dates = array(
            'en' => array(
                'Y/m/d', 'Y-m-d', 'F d, Y',
            ),
            'uk' => array(
                'd/m/Y', 'd-m-Y', 'd F Y',
            ),
        );

        if (in_array(Configure::read('CFG.date_format'), $dates['en'])) {
            return date('Y-m-d', strtotime($date));
        } elseif (in_array(Configure::read('CFG.date_format'), $dates['uk'])) {
            $explode = explode('/', $date);
            $date = $explode[2].'/'.$explode[1].'/'.$explode[0];
            return date('Y-m-d', strtotime($date));
        }
    }
}
