<?php
App::uses('AppModel', 'Model');
App::uses('CakeTime', 'Utility');
/**
 * Program Model
 *
 * @property Race $Race
 * @property Length $Length
 * @property Workout $Workout
 */
class Program extends AppModel {

/**
 * Display field
 *
 * @var string
 */
	public $displayField = 'name';
	public $actsAs = array('Containable');

/**
 * Validation rules
 *
 * @var array
 */
	public $validate = array(
		'name' => array(
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please insert a name for your program.',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'minLength' => array(
				'rule' => array('minLength', 4),
				'message' => 'The name must be at least 4 characters long.',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'race_id' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'workout_level_id' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'race' => array(
			'date' => array(
				'rule' => array('date'),
				'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'check' => array
			(
				'rule' => array('checkRace'),
				'message' => 'You already created a program in that range of time. Please choose a different date.'
			),
			/*
			'past' => array(
				'rule' => array('racePast'),
				'message' => 'Please select a future date.'
			),
			 */
		),
		'training_visual' => array(
			'check' => array(
				'rule' => array('checkTraining'),
				'message' => 'You already created a program in that range of time. Please choose a different date.'
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'training' => array(
			'date' => array(
				'rule' => array('date'),
				'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
		'run_hour' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'bike_hour' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'run_minute' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
			'range' => array( 'rule'    => array('range', -1, 61),
				'message' => 'Please entera value between 0 and 60.'
			),
		),
		'bike_minute' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
			'range' => array(
				'rule'    => array('range', -1, 61),
				'message' => 'Please entera value between 0 and 60.'
			),
		),
		'swim_distance' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'race_year' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'week_last_year' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'week_previous_year' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'week_year_before' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'day_last_year' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'day_previous_year' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'day_year_before' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a number.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				'message' => 'Please enter a number.'
			),
		),
		'training_length' => array(
			'numeric' => array(
				'rule' => array('numeric'),
				'message' => 'Please enter a numeric value.',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
			'between' => array(
				'rule'    => array('range', 0, 21),
				'message' => 'Your training has to be between 1 to 20 weeks long.'
			),
			'notEmpty' => array(
				'rule' => 'notBlank',
				//'message' => 'Your custom message here',
				//'allowEmpty' => false,
				//'required' => false,
				//'last' => false, // Stop validation after this rule
				//'on' => 'create', // Limit validation to 'create' or 'update' operations
			),
		),
	);

/**
 * belongsTo associations
 *
 * @var array
 */
	public $belongsTo = array(
		'Race' => array(
			'className' => 'Race',
			'foreignKey' => 'race_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		),
		'WorkoutLevel' => array(
			'className' => 'WorkoutLevel',
			'foreignKey' => 'workout_level_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		),
		'User' => array(
			'className' => 'User',
			'foreignKey' => 'user_id',
			'conditions' => '',
			'fields' => '',
			'order' => ''
		)
	);

/**
 * hasMany associations
 *
 * @var array
 */
	public $hasMany = array(
		'ProgramChild' => array(
			'className' => 'ProgramChild',
			'foreignKey' => 'program_id',
			'dependent' => false,
			'conditions' => '',
			'fields' => '',
			'order' => '',
			'limit' => '',
			'offset' => '',
			'exclusive' => '',
			'finderQuery' => '',
			'counterQuery' => ''
		),
		'Workout' => array(
			'className' => 'Workout',
			'foreignKey' => 'program_id',
			'dependent' => false,
			'conditions' => '',
			'fields' => '',
			'order' => '',
			'limit' => '',
			'offset' => '',
			'exclusive' => '',
			'finderQuery' => '',
			'counterQuery' => ''
		),
	);

	public function checkTraining($check)
	{
		$training = new DateTime($this->data[$this->alias]['race']);
		$training->modify('-'.$this->data[$this->alias]['training_length'].' weeks');
		$weekDay = (int)$training->format('w');

		if($weekDay!= 1)
		{
			$training->modify('next monday');
		}

		//$this->log($training->format('Y-n-j'));

		$program = $this->find('first', array(
			'conditions' => array(
				'and' => array(
					'user_id =' => CakeSession::read('Auth.User.id'),
					'Program.race >=' => $training->format('Y-n-j'),
					'Program.training <=' => $training->format('Y-n-j'),
					'Program.visible' => 1,
				),
			),
			'fields' => array(
				'id',
				'name',
				'race',
			),
			'contain' => false,
		));

		return empty($program);
	}

	public function checkRace($check)
	{
		$program = $this->find('first', array(
			'conditions' => array(
				'and' => array(
					'user_id =' => CakeSession::read('Auth.User.id'),
					'Program.race >=' => $check['race'],
					'Program.training <=' => $check['race'],
					'Program.visible' => 1,
				),
			),
			'fields' => array(
				'id',
				'name',
				'race',
			),
			'contain' => false,
		));

		return empty($program);
	}

	public function visible($programId)
	{
		$visible = $this->find('first', array(
			'conditions' => array(
				'Program.id' => $programId,
			),
			'fields' => array(
				'visible',
			),
		));

		return $visible['Program']['visible'];
	}

    /*
	public function summarize($userId)
	{
		$total = $this->find('first', array(
			'conditions' => array(
				'user_id' => $userId,
			),
			'group' => array(
				'user_id',
			),
			'fields' => array(
				'SUM(Program.training_charged) AS total'
			),
		));

		if (empty($total))
		{
			return 0;
		}

		return $total[0]['total'];
	}
    */

	public function afterSave($created, $options = array())
	{
        /*
		$program = $this->find('first', array(
			'conditions' => array(
				'Program.id' => $this->data['Program']['id'],
			),
			'recursive' => -1,
		));

		//$this->log($this->summarize($program['Program']['user_id']));

		$summary = $this->summarize($program['Program']['user_id']);
		$this->User->id = $program['Program']['user_id'];
		$this->User->saveField('credits_used', $summary);
        */
	}

	public function racePast($check)
	{
		$race = new DateTime($check['race']);
		return $this->_checkPast($race);
	}

	public function trainingVisualPast($check)
	{
		$trainingVisual = new DateTime($check['training_visual']['year'] . '-' . $check['training_visual']['month'] . '-' . $check['training_visual']['day']);
		return $this->_checkPast($trainingVisual);
	}

	private function _checkPast($check)
	{
		$now = new DateTime();
		return ($now < $check) ? true : false;
	}

	public function findAndSortByDate($date, $userId)
	{
		$start = clone $date; $start->modify('- 12 days');
		$end = clone $date; $end->modify('next month'); $end->modify('+ 12 days');
        //$this->User->isTryingout() ||
        $conditions = array(
			'Workout.date >=' => $start->format('Y-m-d'),
			'Workout.date <=' => $end->format('Y-m-d'),
        );
        /*
		$start = clone $date; $start->modify('- 12 days');
		$end = clone $date; $end->modify('next month'); $end->modify('+ 12 days');
        //$this->User->isTryingout() ||
        if($this->User->isSubscribed()) {
    		$start = clone $date; $start->modify('- 12 days');
    		$end = clone $date; $end->modify('next month'); $end->modify('+ 12 days');

            $conditions = array(
				'Workout.date >=' => $start->format('Y-m-d'),
				'Workout.date <=' => $end->format('Y-m-d'),
            );
        } else {
            $conditions = array(
				'Workout.date >=' => $start->format('Y-m-d'),
				'Workout.date <=' => $end->format('Y-m-d'),
                'Workout.trainingweek' => array(1, 2),
            );
        }
        */

		$programs = $this->find('all',array
		(
			'conditions' => array
			(
				'Program.user_id' => $userId,
				'Program.visible' => true,
			),
			'contain' => array
			(
				'Workout' => array(
					'conditions' => $conditions,
					'Sport' => array(
						'name',
						'value',
						'Measurement' => array(
							'value',
							'symbol'
						),
					),
					'Zone',
					'StrengthType' => array(
						'name',
						'value',
					),
				),
				'Race',
			),
		));

		$entries = array();
		$date = new DateTime();

		foreach($programs as $key => $program)
		{
			$programDates = array(
				'training' => $program['Program']['training'],
				'race' => $program['Program']['race'],
			);

			foreach($programDates as $key => $programDate)
			{
				$date->modify($programDate);

				if(!isset($entries[$date->format('Y-n-j')][$key]))
				{
					$entries[$date->format('Y-n-j')][$key] = array();
				}

				$entries[$date->format('Y-n-j')][$key] = $program['Program'];
			}

			foreach($program['Workout'] as $workout)
			{
				$date->modify($workout['date']);

				if(!isset($entries[$date->format('Y-n-j')][$workout['Sport']['value']]))
				{
					$entries[$date->format('Y-n-j')][$workout['Sport']['value']] = array();
				}

				$workout['race_id'] = $program['Program']['race_id'];
				$entries[$date->format('Y-n-j')][$workout['Sport']['value']] = $workout;
			}

		}

		return $entries;
	}
}
