<?php
/*
 * PHP version 5
 *
 * @copyright Copyright 2010, Cake. (http://trpgtools-onweb.sourceforge.jp/)
 * @category Model
 * @package  TRPG Data Bank
 * @version  beta
 * @author   Cake <cake_67@users.sourceforge.jp>
 * @license  http://www.opensource.org/licenses/mit-license.php The MIT License
 * @link     http://trpgtools-onweb.sourceforge.jp/
 */

class Character extends AppModel {

	var $name = 'Character';

	var $actsAs = array(
		'tags.taggable',
		'Count.CountUp',
	);

	var $status = array(
		'active' => 1,
		'inactive' => 2,
	);

	var $status2 = array(
	);

	var $fields = array(
		'add' => array('name', 'system_id', 'sort_order', 'status', 'public_flag', 'user_id', 'notes', 'secret_notes'),
		'edit' => array('name', 'sort_order', 'status', 'public_flag', 'notes', 'secret_notes'),
		'escape' => array(
			'name' => array(
				'html' => true,
				'tags' => true,
				'all' => true,
			),
			'notes' => array(
				'html' => true,
				'tags' => true,
				'images' => true,
				'sctipts' => true,
			),
			'secret_notes' => array(
				'html' => true,
				'tags' => true,
				'images' => true,
				'sctipts' => true,
			),
		),
		// other 'system_id', 'deleted''deleted_date' 
	);

	var $validate = array(
		'name' => array(
			'notEmpty' => array(
				'rule' => 'notEmpty',
			),
		),
		'system_id' => array(
			'validSystemId' => array(
				'rule' => array('validSystemId', true),
			),
		),
		'sort_order' => array(
			'numeric' => array(
				'rule' => 'numeric',
				'allowEmpty' => true,
			),
		),
		'status' => array(
			'validStatus' => array(
				'rule' => 'validStatus',
				'allowEmpty' => true,
			),
		),
		'public_flag' => array(
			'publicFlag' => array(
				'rule' => 'publicFlag',
				'allowEmpty' => true,
			),
		),
		'user_id' => array(
			'validUserId' => array(
				'rule' => 'validUserId',
			),
		),
	);

	//The Associations below have been created with all possible keys, those that are not needed can be removed
	var $belongsTo = array(
		'System' => array(
			'className' => 'System',
			'foreignKey' => 'system_id',
			'conditions' => array(
				'System.public_flag' => 1,
			),
			'fields' => array(
				'System.id', 
				'System.name', 
				'System.public_flag',
				'System.set_npc',
				'System.copyright',
			),
		),
		'User' => array(
			'className' => 'User',
			'foreignKey' => 'user_id',
			'conditions' => '',
			'fields' => array(
				'User.id', 
				'User.name'
			),
		)
	);

	var $hasMany = array(
		// キャライメージ
		'CharacterPicture' => array(
			'className' => 'CharacterPicture',
			'foreignKey' => 'character_id',
			'dependent' => false,
			'conditions' => array(
				'CharacterPicture.public_flag' => 1,
			),
			'fields' => array(
				'CharacterPicture.id',
				'CharacterPicture.public_flag',
				'CharacterPicture.created',
			),
			'order' => array('CharacterPicture.id' => 'asc'),
			'limit' => '',
			'offset' => '',
			'finderQuery' => '',
			'deleteQuery' => '',
			'insertQuery' => ''
		),
		'CharactersHasProfile' => array(
			'className' => 'CharactersHasProfile',
			'foreignKey' => 'character_id',
			'dependent' => false,
			'conditions' => '',
			'fields' => '',
			'order' => array('CharactersHasProfile.id' => 'asc'),
			'limit' => '',
			'offset' => '',
			'finderQuery' => '',
			'deleteQuery' => '',
			'insertQuery' => ''
		),
		'CharacterProfileArchive' => array(
			'className' => 'CharacterProfileArchive',
			'foreignKey' => 'character_id',
			'dependent' => false,
			'conditions' => array(
				'CharacterProfileArchive.deleted' => '0',
				'CharacterProfileArchive.public_flag' => 1,
			),
			'fields' => array(
				'CharacterProfileArchive.id',
				'CharacterProfileArchive.title',
				'CharacterProfileArchive.public_flag',
				'CharacterProfileArchive.disp_date',
			),
			'order' => array(
				'CharacterProfileArchive.disp_date' => 'desc',
			),
			'limit' => '5',
			'offset' => '',
			'exclusive' => '',
			'finderQuery' => '',
			'counterQuery' => ''
		),
	);

	/* validation Rule */
	function validStatus($data) 
	{
		if (isset($data["status"]) && in_array($data["status"], $this->status)) {
			return true;
		} else {
			return false;
		}
	}

	/* コールバックメソッド */
	function beforeSave($options = array())
	{
		if (empty($this->data['Character']['sort_order'])) {
			$this->data['Character']['sort_order'] = 0;
		}

		$result = parent::beforeSave($options);
		if ($result === false) {
			return $result;
		}

		// textarea
		if (!empty($this->data['Character']['notes'])) {
			$this->data['Character']['notes'] = str_replace(array("\n\r", '\n', "\r"), '<br />', $this->data['Character']['notes']);
		}
		if (!empty($this->data['Character']['secret_notes'])) {
			$this->data['Character']['secret_notes'] = str_replace(array("\n\r", '\n', "\r"), '<br />', $this->data['Character']['secret_notes']);
		}

		return $result;
	}

	function afterSave($created) {
		$this->deleteCache4Charcter();

		return parent::afterSave($created);
	}
	function afterDelete() {
		$this->deleteCache4Charcter();

		return parent::afterDelete();
	}

	/* 共通関数 */
	function get_character($id, $conditions = array(), $isAdmin = false, $contain = array())
	{
		$conditions = array_merge(
			array(
				'Character.id' => $id,
				'Character.deleted' => 0,
			), $conditions
		);

		$this->System->Profile->hasMany['CharactersHasProfile']['conditions']['CharactersHasProfile.character_id'] = $id;
		unset($this->belongsTo['System']['conditions']['System.public_flag']);
		unset($this->hasMany['CharacterPicture']['conditions']['CharacterPicture.public_flag']);
		if ($isAdmin === true) {
			unset($this->System->hasMany['CharacterSheet']['conditions']['CharacterSheet.public_flag']);
			unset($this->hasMany['CharacterProfileArchive']['conditions']['CharacterProfileArchive.public_flag']);
		}

		$contain = array_merge(array(
				'User',
				'CharacterPicture' => array(
					'Attachment',
				),
				'System' => array(
					'CharacterSheet',
					'Profile' => array(
						'ProfileSelect',
						'ProfileTable' => array(
							'ProfileTableStatic',
						),
						'CharactersHasProfile',
						'DefaultProfile',
					),
				),
				'CharacterProfileArchive',
				'Tag',
				'Count',
			), $contain
		);
		$character = $this->find('first', array(
			'conditions' => $conditions,
			'contain' => $contain,
			'recursive' => 4,
		));

		return $character;
	}

	function set_profiles2view($orig_character, $isArchive = false)
	{
		if (!empty($orig_character['System']['Profile'])) {
			$new_profile = array();
			$sort_order = array();
			foreach ($orig_character['System']['Profile'] as $k => $profile) {
				if (isset($profile['sort_order'])  && !empty($profile)) {
					$sort_order[$k] = $profile['sort_order'];
				} else {
					$sort_order[$k] = 0;
				}

				$new_profile[$profile['key_name']]['id'] = $profile['id'];
				$new_profile[$profile['key_name']]['name'] = $profile['name'];
				$new_profile[$profile['key_name']]['profile_type'] = $profile['profile_type'];
				if (!empty($profile['ProfileTable'])) {
					$new_profile[$profile['key_name']]['ProfileTable'] = $profile['ProfileTable'];
				}
				if (CorePlus::get_profile_type($profile['profile_type']) == 's-table' && empty($profile['CharactersHasProfile'])) {
					if (isset($profile['ProfileTable'][0]['ProfileTableStatic'])) {
						foreach ($profile['ProfileTable'][0]['ProfileTableStatic'] as $k2 => $v2) {
							$new_profile[$profile['key_name']]['CharactersHasProfile'][] = $this->_set_blank4static_table($profile['ProfileTable'][0]['ProfileTableStatic'][$k2]['title'], $profile['ProfileTable'][0]['profile_id'], $profile['ProfileTable'][0]['id']);
							for ($i=1;$i<count($profile['ProfileTable']);$i++) {
								$new_profile[$profile['key_name']]['CharactersHasProfile'][] = $this->_set_blank4static_table(null, $profile['ProfileTable'][$i]['profile_id'], $profile['ProfileTable'][$i]['id']);

							}
						}
					} else {
						$new_profile[$profile['key_name']]['CharactersHasProfile'] = null;
					}
				} else {
					$new_profile[$profile['key_name']]['CharactersHasProfile'] = $profile['CharactersHasProfile'];
				}
			}

			array_multisort($sort_order, SORT_ASC, $new_profile);

			$orig_character['System']['Profile'] = $new_profile;
		}

		$character['Character'] = $orig_character['Character'];
		if ($isArchive === true) {
//			beforeSerialize($character['Character']['name']);
//			beforeSerialize($character['Character']['notes']);
		}

		if (isset($orig_character['CharacterPicture'])) {
			$character['CharacterPicture'] = $orig_character['CharacterPicture'];
		}
		if (isset($orig_character['Tag'])) {
			$character['Tag'] = $orig_character['Tag'];
		}
		if (isset($orig_character['Count'])) {
			$character['Count'] = $orig_character['Count'];
		}
		if (isset($orig_character['CharacterProfileArchive']) && $isArchive !== true) {
			$character['CharacterProfileArchive'] = $orig_character['CharacterProfileArchive'];
		}
		if (isset($orig_character['System'])) {
			if ($isArchive === true) {
				unset($orig_character['System']['CharacterSheet']);
				unset($orig_character['System']['copyright']);
				unset($orig_character['System']['detail']);
				unset($orig_character['System']['ad']);
			}

			$character['System'] = $orig_character['System'];
		}

		if (isset($orig_character['User'])) {
			$character['User'] = $orig_character['User'];
		}

		return $character;
	}

	function _set_blank4static_table($value, $profile_id, $profile_table_id)
	{
		return array(
			'profile_id' => $profile_id,
			'profile_table_id' => $profile_table_id,
			'value' => $value,
			'public_flag' => 1,
		);
	}

	function saveCharacterProfile($id, $params = array())
	{
		if (empty($id)) {
			return false;
		}
		if (isset($params['CharacterProfileArchive'])) {
			$params = array($params['CharacterProfileArchive']);
		} else {
			$params = array();
		}

		$archive['CharacterProfileArchive']['character_id'] = $id;

		$character = $this->get_character($id, array(), true);

		$newData = $this->set_profiles2view($character, true);
		array_walk_recursive($newData, 'beforeSerialize');

		$archive['CharacterProfileArchive']['value'] = serialize($newData);

		$archive['CharacterProfileArchive']['title'] = $params[0]['title'];
		$archive['CharacterProfileArchive']['memo'] = $params[0]['memo'];

		if (isset($params['disp_date'])) {
			$archive['CharacterProfileArchive']['disp_date'] = $params['disp_date'];
		} else {
			$archive['CharacterProfileArchive']['disp_date'] = date('Y-m-d H:i:s');
		}

		if ($character['Character']['public_flag'] != 1) {
			$archive['CharacterProfileArchive']['public_flag'] = $character['Character']['public_flag'];
		} else {
			$archive['CharacterProfileArchive']['public_flag'] = $params[0]['public_flag'];
		}

		$this->CharacterProfileArchive->create();
		if ($this->CharacterProfileArchive->save($archive, array('fieldList' => $this->CharacterProfileArchive->fields['add']))) {
			return true;
		} else {
			return false;
		}
	}

	/* Paginate */
	function paginateCount($conditions = null, $recursive = 0, $extra = array()) {
		if ($this->checkSearchProfile($conditions)) {
			unset($conditions['profile_search']);

			$character_ids = $this->_getCharactersByCharacterProfiles($conditions);

			return count($character_ids);
		} else {
			// 元のpaginateCount(controller.phpより)
			$parameters = compact('conditions');
			if ($recursive != $this->recursive) {
				$parameters['recursive'] = $recursive;
			}
			$count = $this->find('count', array_merge($parameters, $extra));
			return $count;
		}
	}

	function paginate($conditions = array(), $fields = null, $order = null, $limit = 20, $page = 1, $recursive = -1, $extra = array()) {
		if ($this->checkSearchProfile($conditions)) {
			unset($conditions['profile_search']);

			$character_ids =  $this->_getCharactersByCharacterProfiles($conditions);

			if (empty($character_ids)) {
				return array();
			}

			$conditions = array(
				'Character.id' => array_values($character_ids),
			);
		}

		$params = array(
			'conditions' => $conditions,
			'fields' => $fields,
			'order' => $order,
			'limit' => $limit,
			'page' => $page,
		);
		if (isset($extra['contain'])) {
			$params['contain'] = $extra['contain'];
		}

		$results = $this->find('all', $params);

		return $results;
	}

	function checkSearchProfile($conditions = array())
	{
		if (isset($conditions['profile_search'])) {
			return true;
		} else {
			return false;
		}
	}

	function _getCharactersByCharacterProfiles($conditions = null)
	{
		static $character_ids;
		static $prev_conditions;

		if (!empty($character_ids) && $prev_conditions == $conditions)  {
			return $character_ids;
		}

		$prev_conditions = $conditions;

		$this->CharactersHasProfile->unbindModel(
			array('belongsTo' => array(
				'Profile',
				'ProfileSelect',
				'ProfileTable',
				'ProfileTableStatic',
			)
		));
		return $character_ids = $this->CharactersHasProfile->find('list', array(
			'conditions' => $conditions,
			'fields' => array('CharactersHasProfile.character_id'),
			'group' => ('CharactersHasProfile.character_id'),
			'recursive' => 1,
		));
	}

	/* キャッシュ削除 */
	function deleteCache4Charcter()
	{
		// 自セッション関連
		$this->deleteCacheMyData();

		$this->deleteCacheCharacter($this->id, false);

		if (isset($this->data['clearCache'])) {
			$this->deleteCacheHome($this->data['clearCache']['user_id']);
			$this->deleteCacheUser($this->data['clearCache']['user_id']);
			$this->deleteCacheSystem($this->data['clearCache']['system_id'], false); // System一覧の更新遅れを修正する場合true
		} else {
			$this->deleteCacheHome();
		}

		// ProfileArchive
		$this->deleteCache4ProfileArchivesIndex($this->id);
	}
}

function beforeSerialize(&$item)
{
	$item = preg_replace('/\\\n/', "<br />", $item);
	$item = addslashes($item);

	return $item;
}
