<?php
/*
 * PHP version 5
 *
 * @copyright Copyright 2010, Cake. (http://trpgtools-onweb.sourceforge.jp/)
 * @category Controller
 * @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 CharactersController extends AppController {

	var $name = 'Characters';
	var $helpers = array(
		'Select',
		'Profiledisp',
	);

	/* テーマ */
	var $view = 'View';
	var $theme = null;

	var $isNpc = false;

	var $disableTokenActions = array();
	var $post_data = array();

	// 検索対象項目
	var $search_cols = array(
	);

	/* メソッド */

	function beforeFilter() {

		parent::beforeFilter();

		// Cache
		$this->cacheAction = array(
			'index' => Configure::read('Cache.expireShort'),
		);

		// 認証なしアクセス可
		$this->AuthPlus->allow('view');
		$this->AuthPlus->allow('index');
		$this->AuthPlus->allow('search');

		// 設定
		$this->set_public_flag4view();
		$this->set_status4view();
	}

	function beforeRender()
	{
		parent::beforeRender();
	}


	/* アクションメソッド */

	function index($id = null) {
		if (!empty($id) && $id == $this->user_id) {
			$this->redirect(array_merge(array('action'=>'mycharacter'), $this->params['named']));
		}

		$this->set('isOwner', false);

		$this->_index($id);
	}

	function search($id = null) {
		if (!empty($id) && $id == $this->user_id) {
			$this->redirect(array_merge(array('action'=>'mysearch'), $this->params['named']));
		}

		$this->set('isOwner', false);

		$this->_search($id);
	}

	function mysearch(){
		$this->set('isOwner', true);

		$this->_search($this->user_id);
	}

	function mycharacter(){
		// お知らせ
		$news = array();
		if (empty($this->site_configs['Site.myHome']['value'])) {
			$news = $this->get_news();
		}
		$this->set('news', $news);

		$this->set('isOwner', true);

		$this->_index($this->user_id);
	}

	function view($id = null) {
		if (!$id) {
			$this->Session->setFlash(__('Invalid Character.', true));
			$this->redirect(array('action'=>'index'));
		}

		$character = $this->_view($id, array(), false);
		// Systemチェック
		if (!$this->check_public_flag($character['System'])) {
			unset($character['System']['Profile']);
		}

		$this->set('maxPictures', $this->check_character_picture_max(count($character['CharacterPicture'])));

		$isOwner = false;
		if ($this->isOwner($character['Character'], $this->user_id)) {
			$isOwner = true;
		}
		$this->set('isOwner', $isOwner);

		// キャラ画像のpublic_flagチェック
		if ($isOwner !== true && !empty($character['CharacterPicture'])) {
			foreach($character['CharacterPicture'] as $k => $v) {
				if (!$this->check_public_flag2($v)) {
					unset($character['CharacterPicture'][$k]);
				}
			}
		}

		$this->set('character', $this->HtmlEscape->nl2br_escaped($character));
	}

	function add() {
		$systems = $this->_get_systems('public');
		// SingleSystem
		if (isset($this->site_configs['System.singleSystem']['value']) && $this->site_configs['System.singleSystem']['value']) {
			$this->params['named']['system_id'] = key($systems);
		}

		if (isset($this->params['named']['system_id']) && !empty($this->params['named']['system_id'])) {
			$system = $this->Character->System->find('first', array(
				'conditions' => array(
					'System.id' => $this->params['named']['system_id'],
				),
				'recursive' => -1,
				'fields' => array(
					'System.id',
					'System.name',
					'System.public_flag',
					'System.set_npc',
				)
			));
			if (empty($system) || !$this->check_public_flag2($system['System'])) {
				$this->Session->setFlash(__('Invalid ID.', true));
				$this->redirect(array('action'=>'index'));
			}
		}
/*		if (isset($system['System']) && !empty($system['System']) && $system['System']['set_npc']) {
			$this->isNpc = true;
		}*/

		if (!empty($this->data)) {
			$this->data['Character']['user_id'] = $this->user_id;
			if (isset($this->site_configs['System.singleSystem']['value']) && $this->site_configs['System.singleSystem']['value']) {
				$this->data['Character']['system_id'] = key($systems);
			}

			$this->Character->create();
			if ($this->Character->save($this->data, array('fieldList' => $this->Character->fields['add']))) {

				$this->Session->setFlash(sprintf(__('%s has been saved.', true), $this->data['Character']['name']));
				$this->redirect(array('controller' => 'characters', 'action'=>'view', $this->Character->id));
			} else {
				$this->Session->setFlash(__('The data could not be saved. Please, try again.', true));
			}
		}

		$this->set('systems', $systems);
		$this->set('isOwner', false);

		$this->set('title_for_layout', " ". __('Add Character', true));
	}

	function edit($id = null) {
		if (!$id && empty($this->data)) {
			$this->Session->setFlash(__('Invalid ID.', true));
			$this->redirect(array('action'=>'index'));
		}

		// Characterデータ取得
		unset($this->Character->System->hasMany['Profile']['fields']);
		$this->Character->System->Profile->hasMany['CharactersHasProfile']['fields'] = '';
		unset($this->Character->hasMany['CharacterProfileArchive']);

		$character = $this->_get_character($id, array(), false);
		if (!$this->isOwner($character['Character'], $this->user_id)) {
			$this->Session->setFlash(__('No Permission', true));
			$this->redirect(array('action'=>'index'));
		}

		// Systemチェック
		if (!$this->check_public_flag($character['System'])) {
			$this->redirect(array('action'=>'change_system', $id));
		}
/*		if ($character['System']['set_npc']) {
			$this->isNpc = true;
		}*/

		if (empty($this->data)) {
			$character['System']['Profile'] = $this->_set_profile_table2characters_has_profiles($character['System']['Profile']);
		}

		if (!empty($this->data)) {
			$this->post_data = $this->data;

			$this->data['clearCache'] = array(
				'character_id' => $id,
				'user_id' => $this->user_id,
				'system_id' => $character['System']['id'],
			);

			// 新hasProfile処理
			if (isset($this->data['CharactersHasProfile'])) {
				$this->data['CharactersHasProfile'] = $this->_set_new_characters_has_profile($this->data['CharactersHasProfile']);
			}

			/* validate */
			$this->_set_validate4characters_has_profile($character['System']['id']);

			if ($this->Character->saveAll($this->data, array('validate' => 'only'))) {
				// requiredのチェック
				$requiredCheck = $this->_checkRequiredProfile($character['System']['Profile']);

				if ($requiredCheck) {
					// 現在のhas_profiles削除
					$this->Character->CharactersHasProfile->deleteAll(array(
						'CharactersHasProfile.character_id' => $id
					));

					/* データ保存 */
					$this->data['Character']['id'] = $id;
					$this->Character->create();

					if ($this->Character->saveAll($this->data, array(
						'validate' => false,
						 'fieldList' => array_merge(
						 	$this->Character->fields['edit'], 
						 	$this->Character->CharactersHasProfile->fields['add']
						 )
					))) {

						// Archives保存
						if (isset($this->data['Character']['archive']) && $this->data['Character']['archive'] == 1) {
							$this->Character->saveCharacterProfile($this->Character->id, $this->data); 
						}

						$this->Session->setFlash(sprintf(__('%s has been saved.', true), $this->data['Character']['name']));
						$this->redirect(array('action'=>'view', $id));
					}
				}
			} else {
				$validate_error = current(current(current($this->Character->validationErrors)));
				$this->Session->setFlash($validate_error);
			}

			$this->data = array_merge($character, $this->post_data);
			$this->data['Character'] = $this->post_data['Character'];
			$this->data['Character']['main_picture'] = $character['Character']['main_picture'];
			$this->data['Character']['system_id'] = $character['Character']['system_id'];
			$this->data['Character']['id'] = $id;
			foreach ($this->data['System']['Profile'] as $k1 => $profile) {
				if ($profile['profile_type'] == 'table') {
					$colum_num = count($profile['CharactersHasProfile']);
				} elseif ($profile['profile_type'] == 's-table') {
					$colum_num = count($profile['CharactersHasProfile']);
				} elseif ($profile['profile_type'] == 'checkbox') {
					$colum_num = count($profile['ProfileSelect']);
				} elseif ($profile['profile_type'] == 'm-input') {
					$colum_num = count($profile['CharactersHasProfile']);
				} else {
					$colum_num = 1;
				}

				if ($colum_num == 0) {
					if ($profile['profile_type'] == 's-table') {
						$colum_num = count($profile['ProfileTable']) * count($profile['ProfileTable'][0]['ProfileTableStatic']);
					} elseif ($profile['profile_type'] == 'table') {
						$colum_num = count($profile['ProfileTable']) * 4;
					} elseif ($profile['profile_type'] == 'checkbox') {
						$colum_num = count($profile['ProfileSelect']);
					} elseif ($profile['profile_type'] == 'm-input') {
						$colum_num = 5;
					} else {
						$colum_num = 1;
					}
				}

				for ($i=0; $i<$colum_num; $i++) {
					if (!isset($profile['CharactersHasProfile'][$i])) {
						$profile['CharactersHasProfile'][$i] = array('character_id' => $character['Character']['id']);
					}

					$postdata = array_shift($this->post_data['CharactersHasProfile']);

					if (is_array($postdata['value'])) {
						$postdata['value'] = $postdata['value'][0];
					}

					if (isset($postdata[$i])) {
						$this->data['System']['Profile'][$k1]['CharactersHasProfile'][$i] = array_merge($profile['CharactersHasProfile'][$i], $postdata[$i]);
					} else {
						$this->data['System']['Profile'][$k1]['CharactersHasProfile'][$i] = array_merge($profile['CharactersHasProfile'][$i], (array)$postdata);
					}
				}
			}
		}

		elseif (empty($this->data)) {
			$this->data = $character;
			$this->data['Character'] = $this->_restore_html_character($this->data['Character'], true);

		}
		$this->data['System']['Profile'] = $this->_restore_html_characters_has_profiles($this->data['System']['Profile'], true);

		$this->set('isOwner', true);

		$this->set('title_for_layout', " ". sprintf(__('Edit %s', true), $character['Character']['name']));
	}

	function add_multi_profiles($id = null) {
		if (!$id || !CorePlus::is_valid($this->params['named'], 'profile_id')) {
			$this->Session->setFlash(__('Invalid ID.', true));
			$this->redirect(array('action'=>'index'));
		}

		// Characterデータ取得
		$this->Character->System->hasMany['Profile']['fields'] = '';
		$this->Character->System->Profile->hasMany['CharactersHasProfile']['fields'] = '';
		unset($this->Character->hasMany['CharacterProfileArchive']);

		$character = $this->_get_character($id);
		if (!$this->isOwner($character['Character'], $this->user_id)) {
			$this->Session->setFlash(__('No Permission', true));
			$this->redirect(array('action'=>'index'));
		}
		// Systemチェック
		if (!$this->check_public_flag($character['System'])) {
			$this->redirect(array('action'=>'change_system', $id));
		}

		// Profilesデータ取得
		if (empty($character['System']['Profile'])) {
			$this->Session->setFlash(__('Invalid Profile.', true));
			$this->redirect(array('action'=>'view', $id));
		}

		$profile_id = $this->params['named']['profile_id'];

		$target = array();
		foreach ($character['System']['Profile'] as $profile) {
			if ($profile['id'] == $profile_id) {
				$target = $profile;
				break;
			}
		}

		if (!$target) {
			$this->Session->setFlash(__('No Profile.', true));
			$this->redirect(array('action'=>'view', $id));
		}

		$character['System']['Profile'] = array();
		$character['System']['Profile'][0] = $target;

		$character['System']['Profile'] = $this->_set_profile_table2characters_has_profiles($character['System']['Profile']);

		if (!empty($this->data)) {
			$this->data['clearCache'] = array(
				'character_id' => $id,
				'user_id' => $this->user_id,
				'system_id' => $character['System']['id'],
			);

			$this->post_data = $this->data;
			$this->data = array();
			if (isset($this->post_data['Character'])) {
				$this->data['Character'] = array_merge($character['Character'], $this->post_data['Character']);
			} else {
				$this->data['Character'] = $character['Character'];
			}
			$this->data['Character'] = $this->_restore_html_character($this->data['Character']);
			$this->data['Character']['__Token'] = $this->post_data['Character']['__Token'];
			$this->data['Character']['modified'] = null;

			// 新hasProfile処理
			$this->data['CharactersHasProfile'] = $this->_set_new_characters_has_profile($this->post_data['CharactersHasProfile'], $profile_id, $character['System']['Profile']);

			// Archive
			$this->data['CharacterProfileArchive'] = $this->post_data['CharacterProfileArchive'];

			/* validate */
			$this->_set_validate4characters_has_profile($character['System']['id']);
			if ($this->Character->saveAll($this->data, array('validate' => 'only'))) {
				// requiredのチェック
				$requiredCheck = $this->_checkRequiredProfile($character['System']['Profile']);

				if ($requiredCheck) {
					// 現在のhas_profiles削除
					$this->Character->CharactersHasProfile->deleteAll(array(
						'CharactersHasProfile.profile_id' => $target['id'],
						'CharactersHasProfile.character_id' => $id
					));

					/* データ保存 */
					$this->Character->create();
					if ($this->Character->saveAll($this->data, array(
						'validate' => false,
						 'fieldList' => array_merge(
						 	$this->Character->CharactersHasProfile->fields['add']
						 )
					))) {

						// Archives保存
						if (isset($this->data['Character']['archive']) && $this->data['Character']['archive'] == 1) {
							$this->Character->saveCharacterProfile($this->Character->id, $this->data);
						}

						$this->Session->setFlash(sprintf(__('%s has been saved.', true), $this->data['Character']['name']));
						$this->redirect(array('action'=>'view', $id));
					} else {
						$this->data = array_merge($character, $this->data);
					}
				} else {
				}
			} else {
				$validate_error = current(current(current($this->Character->validationErrors)));
				$this->Session->setFlash($validate_error);
			}

			$this->data = array_merge($character, $this->data);
			$this->data['Character']['id'] = $id;
			unset($this->data['Character']['__Token']);

		}

		if (empty($this->data)) {
			$this->data = $character;
		}
		$this->data['System']['Profile'] = $this->_restore_html_characters_has_profiles($this->data['System']['Profile']);

		$this->set('isOwner', true);

		if (isset($this->params['named']['num'])) {
			$form_nums = $this->params['named']['num'];
		} else {
			$form_nums = 3;
		}
		$this->set('form_nums', $form_nums);

		$this->set('title_for_layout', " ". sprintf(__('Edit %s', true), $character['Character']['name']));
	}

	function change_system($id = null) {
		if (!$id) {
			$this->Session->setFlash(__('Invalid ID.', true));
			$this->redirect(array('action'=>'index'));
		}

		// Characterデータ取得
		$this->Character->System->hasMany['Profile']['fields'] = '';
		$this->Character->System->Profile->hasMany['CharactersHasProfile']['fields'] = '';

		$character = $this->_get_character($id);
		if (!$this->isOwner($character['Character'], $this->user_id)) {
			$this->Session->setFlash(__('No Permission', true));
			$this->redirect(array('action'=>'index'));
		}

		// Systemチェック
		// Systemあり
		if (isset($character['System']) && !empty($character['System'])) {
			// 「その他」設定
			if ($this->isOtherSystem($character['System']['id'])) {
				$this->set('isChange', true);
			// 公開状態は変更不可
			} elseif ($this->check_public_flag($character['System'])) {
				$this->redirect(array('action'=>'edit', $id));
			// System非公開
			} else {
				$this->set('isChange', true);
			}
		}

		if (!empty($this->data)) {
			$this->data['clearCache'] = array(
				'character_id' => $id,
				'user_id' => $this->user_id,
				'system_id' => $character['System']['id'],
			);

			$this->data['Character']['id'] = $id;

			// validateはsystem_idのみ
			$this->Cahracter['validate'] = array(
				'system_id' => array(
					'validSystemId' => array(
						'rule' => array('validSystemId', true),
						'allowEmpty' => false,
					)
				),
			);

			if ($this->Character->save(
				$this->data,
				array(
					'validate' => true,
					'fieldList' => array('system_id'),
				)
			)) {
				$this->Session->setFlash(__('The new system has been saved', true));
				$this->redirect(array('action'=>'view', $id));
			} else {
				$this->Session->setFlash(__('The data could not be saved. Please, try again.', true));
			}
		}

		$this->set('isOwner', true);
		$this->set('character', $character);

		$systems = $this->_get_systems('public');
		$this->set('systems', $systems);

		$this->set('title_for_layout', " ". sprintf(__('%s Change System', true), $character['Character']['name']));
	}


	function set_status($id = null) {
		if (!$id || !isset($this->params['named']['mode'])) {
			$this->Session->setFlash(__('Invalid ID.', true));
			$this->redirect(array('controller' => 'characters', 'action'=>'index'));
		}

		$character = $this->_get_character4character_id($id, $this->user_id);

		if ($this->params['named']['mode'] != 'main_picture' && $this->params['named']['mode'] != 'full_length') {
			$this->Session->setFlash(__('Invalid URL.', true));
			$this->redirect(array('controller' => 'character_pictures', 'action'=>'index', $id));
		}

		// 新picture設定
		$new_character_picture = null;
		if (isset($this->params['named']['new_picture_id']) && $this->params['named']['new_picture_id'] != 'null') {
			if ($character['CharacterPicture']) {
				foreach($character['CharacterPicture'] as $k => $v) {
					if ($v['id'] == $this->params['named']['new_picture_id']) {
						$new_character_picture = CorePlus::get_value($v, 'Attachment.0.basename');
						break;
					}
				}
			}
			if (!$new_character_picture) {
				$this->Session->setFlash(__('Invalid data.', true));
				$this->redirect(array('controller' => 'character_pictures', 'action'=>'listview', $id));
			}
		}


		$this->data['clearCache'] = array(
			'character_id' => $id,
			'user_id' => $this->user_id,
			'system_id' => $character['Character']['system_id'],
		);

		// 設定変更
		$this->Character->id = $id;
		$this->data['Character'][$this->params['named']['mode']] = $new_character_picture;
		$this->Character->save(
			$this->data, 
			array(
				'fieldList' => array(
					$this->params['named']['mode']
				), 
			)
		);

		$this->Character->deleteCache4CharacterPicture($id);


		$this->Session->setFlash(__('CharacterPicture Configuration has been saved.', true));
		$this->redirect(array('controller' => 'character_pictures', 'action' => 'listview', $id));
	}

	function delete($id = null) {
		if (!$id) {
			$this->Session->setFlash(__('Invalid id for Character', true));
			$this->redirect(array('action'=>'index'));
		}

		if ($this->_delete($id)) {
			$this->redirect(array('controller' => 'users', 'action'=>'index'));
		}

		$this->set('title_for_layout', " - ". __('Delete Character', true));
	}

	function admin_index($id = null) {

		$this->_index($id, array('isAdmin' => true));
	}

	function admin_search($id = null) {
		$this->search_cols['Character']['public_flag'] = array(
			'name' => __('Public Flag', true),
			'type' => 'select',
			'options' => CorePlus::set_publicflag($this->model_public_flags, array('all')),
			'default' => 'public',
		);

		$this->_search($id, array('isAdmin' => true));
	}

	function admin_view($id = null) {
		if (!$id) {
			$this->Session->setFlash(__('Invalid Character.', true));
			$this->redirect(array('action' => 'admin_index'));
		}

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

		$this->set('character', $this->HtmlEscape->nl2br_escaped($character));
	}

	function admin_edit($id = null) {
		if (!$id && empty($this->data)) {
			$this->Session->setFlash(__('Invalid ID.', true));
			$this->redirect(array('action'=>'index'));
		}

		// Characterデータ取得
		$this->Character->System->hasMany['Profile']['fields'] = '';
		$this->Character->System->Profile->hasMany['CharactersHasProfile']['fields'] = '';
		unset($this->Character->hasMany['CharacterProfileArchive']);

		$character = $this->_get_character($id, array(), true);
		if (!$character) {
			$this->Session->setFlash(__('No Character', true));
			$this->redirect(array('action'=>'index'));
		}

		if (empty($this->data)) {
			$character['System']['Profile'] = $this->_set_profile_table2characters_has_profiles($character['System']['Profile']);
		}

		if (!empty($this->data)) {

			$this->data['clearCache'] = array(
				'character_id' => $id,
				'user_id' => $this->user_id,
				'system_id' => $character['System']['id'],
			);

			if (isset($this->data['Character']['mode']) && $this->data['Character']['mode'] == 'set_private') {
				$this->data['Character']['public_flag'] = 'private';
			} elseif (isset($this->data['Character']['mode']) && $this->data['Character']['mode'] == 'set_public') {
				$this->data['Character']['public_flag'] = 'public';
			} elseif (isset($this->data['Character']['mode']) && $this->data['Character']['mode'] == 'delete_confirm') {
				$this->redirect(array('controller' => 'characters', 'action'=>'admin_delete', $id));
			} else {
				$this->Session->setFlash(sprintf(__('Invalid data.', true), $this->data['Character']['name']));
				$this->redirect(array('action'=>'view', $id));
			}

			$this->data['Character']['id'] = $id;
			$this->Character->create();
			if ($this->Character->save($this->data, array(
				'validate' => true,
				'fieldList' => array(
					'public_flag',
				),
			))) {

					$this->Session->setFlash(sprintf(__('%s has been saved.', true), $character['Character']['name']));
					$this->redirect(array('action'=>'view', $id));
				}

			$this->data = array_merge($character, $this->data);
			$this->data['Character']['id'] = $id;
		}

		if (empty($this->data)) {
			$this->data = $character;
			$this->data['Character'] = $this->_restore_html_character($this->data['Character'], true);

			$this->data['System']['Profile'] = $this->_restore_html_characters_has_profiles($this->data['System']['Profile'], true);
		}

		$this->set('title_for_layout', " ". sprintf(__('Edit %s', true), $character['Character']['name']));
	}

	function admin_delete($id = null) {
		if (!$id) {
			$this->Session->setFlash(__('Invalid id for Character', true));
			$this->redirect(array('action'=>'index'));
		}

		if ($this->_delete($id, array(), true)) {
			$this->redirect(array('action'=>'index'));
		}

		$this->set('title_for_layout', " - ". __('Delete Character', true));
	}


	/* 共通化アクションメソッド */
	function _index($id, $conditions = array(), $limit = 20, $fields = array(), $contain = array(), $order = array(), $page = 1) {
		if (isset($conditions['isAdmin']) && $conditions['isAdmin'] === true) {
			$isAdmin = true;
			unset($this->Character->belongsTo['System']['conditions']['System.public_flag']);
		} else {
			$isAdmin = false;
		}

		$title = __('List of All Characters', true);

		// System指定分岐
		if (isset($this->params['named']['system']) && intval($this->params['named']['system'])) {
			//情報取得
			$this_system = $this->_getThisSystem($this->params['named']['system'], $isAdmin);

			$conditions['Character.system_id'] = $this->params['named']['system'];

			// Profileの一覧表示
			$profiles = $this->Character->System->Profile->find('all', array(
				'fields' => array(
					'Profile.id',
					'Profile.name',
					'Profile.key_name',
					'Profile.profile_type',
					'Profile.sort_order',
				),
				'conditions' => array(
					'Profile.system_id' => $this->params['named']['system'],
					'Profile.show_list' => true,
				),
				'recursive' => -1,
			));
			$prof = array();
			foreach ($profiles as $k => $v) {
				if (isset($v['Profile']['sort_order'])  && !empty($v['Profile']['sort_order'])) {
					$sort_order_profile[$v['Profile']['id']] = $v['Profile']['sort_order'];
				} else {
					$sort_order_profile[$v['Profile']['id']] = 0;
				}

				$prof[$v['Profile']['id']] = array(
					'id' => $v['Profile']['id'],
					'name' => $v['Profile']['name'],
					'key_name' => $v['Profile']['key_name'],
					'profile_type' => $v['Profile']['profile_type'],
				);
			}
			if (!empty($sort_order_profile)) {
				$prof = $this->sort4sort_order($prof, $sort_order_profile);
			}

			foreach ($prof as $k => $v) {
				$this->showlist_cols['Profile'][] = $v['id'];
			}

			$this_system['Profile'] = $prof;

			$this_system = $this->_restore_html_system($this_system);

/*			if ($this_system['System']['set_npc']) {
				$this->isNpc = true;
			}*/

			$title = $this_system['System']['name']. " ". $title;

			$this->set('this_system', $this_system);
		} else {
			$contain = array_merge(array('System'), (array)$contain);

//			$this->isNpc = true;
		}

		$user = array();
		if (!empty($id)) {
			$user = $this->Character->User->find('first', array(
				'conditions' => array('User.id' => $id),
				'recursive' => -1,
				'fields' => array(
					'User.id',
					'User.name',
				),
			));

			if (empty($user)) {
				$this->Session->setFlash(__('Invalid Id.', true));
				$this->redirect(array('action'=>'index'));
			}

			$conditions['Character.user_id'] = $id;
			if ($id == $this->user_id) {
				unset($this->paginate['conditions']['Character.public_flag']);
			}

			$title = $user['User']['name']. " ". $title;
		} else {
			$contain = array_merge($contain, array('User'));
		}
		$this->set('userSet', $user);

		// Status分岐
		if (!isset($this->params['named']['status'])) {
			$status = 'active';
		} else {
			$status = $this->params['named']['status'];
		}
		switch ($status) {
			case 'active':
			case 'inactive':
//			case 'npc':
				$conditions['Character.status'] = $status;
				break;
			default:
				$status = 'all';
				unset($conditions['Character.status']);
				break;
		}
		$this->set('selected_status', $status);

		$characters = $this->HtmlEscape->nl_unescape($this->_get_characters_page4user_id($id, $conditions, $limit, $fields, $contain, $order, $page));

		$this->set('characters', $characters);

		$this->set('title_for_layout', " - ". $title);
	}

	function _search($id, $conditions = array(), $limit = 20) {
		if (isset($conditions['isAdmin']) && $conditions['isAdmin'] === true) {
			$isAdmin = true;
		} else {
			$isAdmin = false;
		}

		if (!isset($this->search_cols['Character'])) {
			$this->search_cols['Character'] = array();
		}

		$system_conditions['System.public_flag'] = 'public';
		if (isset($this->data['Character']['keyword']['system_id'])) {
			if (!empty($this->data['Character']['keyword']['system_id'])) {
				$this->passedArgs['system'] = $this->data['Character']['keyword']['system_id']['value'];
				$system_id = $this->passedArgs['system'];
			}
		} elseif (isset($this->passedArgs['system'])) {
			$system_id = $this->passedArgs['system'];
		} else {
			$system_id = 0;
		}
		$systems = $this->_get_systems('public');
		$systems =
			array(0 => __('All', true)) + $systems;

		$this->search_cols['Character'] = array_merge($this->search_cols['Character'], array(
			'system_id' => array(
				'name' => __('System', true),
				'type' => 'select',
				'options' => $systems,
				'default' => $system_id,
			),
		));

		if (isset($this->passedArgs['status'])) {
			$status = $this->passedArgs['status'];
		} else {
			$status = 'active';
		}

		$this->search_cols['Character'] = array_merge($this->search_cols['Character'], array(
			'status' => array(
				'name' => __('Status', true),
				'type' => 'select',
				'options' => CorePlus::set_status($this->model_status2),
				'default' => $status,
			),
		));

		$this->search_cols['Character'] = array_merge($this->search_cols['Character'], array(
			'name' => array(
				'name' => __('Charater Name', true),
				'type' => 'text',
			),
		));
		if ($this->site_configs['Character.NotesSearch']['value']) {
			$this->search_cols['Character'] = array_merge($this->search_cols['Character'], array(
				'notes' => array(
					'name' => __('Notes', true),
					'type' => 'text',
				)
			));
		}

		// Profileの検索対象
		if (!empty($system_id)) {
			$this_system = $this->_getThisSystem($system_id, $isAdmin);

			$profiles = $this->Character->System->Profile->find('all', array(
				'fields' => array(
					'Profile.id',
					'Profile.name',
					'Profile.key_name',
					'Profile.profile_type',
					'Profile.sort_order',
				),
				'conditions' => array(
					'Profile.system_id' => $system_id,
					'Profile.search' => true,
				),
				'recursive' => -1,
			));
			$prof = array();
			foreach ($profiles as $k => $v) {
				if (isset($v['Profile']['sort_order'])  && !empty($v['Profile']['sort_order'])) {
					$sort_order_profile[$v['Profile']['id']] = $v['Profile']['sort_order'];
				} else {
					$sort_order_profile[$v['Profile']['id']] = 0;
				}

				$prof[$v['Profile']['id']] = array(
					'id' => $v['Profile']['id'],
					'name' => $v['Profile']['name'],
//					'key_name' => $v['Profile']['key_name'],
//					'profile_type' => $v['Profile']['profile_type'],
				);
			}
			if (!empty($sort_order_profile)) {
				$prof = $this->sort4sort_order($prof, $sort_order_profile);
			}

			foreach ($prof as $k => $v) {
				$this->search_cols['CharactersHasProfile'][$v['id']] = array(
					'name' => $v['name'],
					'type' => 'text',
				);
			}
		}

		if (!empty($id) && ($this->user['User']['id'] == $id)) {
			$isAdmin = true;
		}

		$this->set('search_cols', $this->search_cols);

		if ($this->site_configs['Character.ListSearchNotes']['value'] || $this->site_configs['Character.NotesSearch']['value']) {
			$this->fields = array_merge($this->fields, array('Character.notes'));
		}
//		$this->set('fields', $this->fields);

		// 検索条件設定
		$type = 'OR';

		$page = 1;
		if (!empty($this->data)) {
			if (isset($this->data['Character']['page']) && $this->data['Character']['page'] > 0) {
				$page = $this->data['Character']['page'];
				unset($this->data['Character']['page']);
			}

			$prev_type = 'AND';
			$prev_type_set = false;
			$new_condition = null;
			foreach ($this->data as $model => $search_conditions) {
				$keywords = array();
				if (isset($search_conditions['keyword']) && !empty($search_conditions['keyword'])) {
					foreach ($search_conditions['keyword'] as $field => $search_options) {
						switch($model) {
							case 'Character':
								if ($field == 'public_flag') {
									if (isset($conditions['isAdmin']) && !empty($conditions['isAdmin']) && $search_options['value'] == 'all') {
										unset($this->paginate['conditions']['Character.public_flag']);
									} else {
										$conditions['Character.public_flag'] = $search_options['value'];
										$conditions['public_force'] = true;
									}
								} elseif ($field == 'system_id') {
									if (empty($search_options['value'])) {
										if (isset($this->params['named']['system'])) {
											unset($this->params['named']['system']);
										}
									} else {
										$this->params['named']['system'] = $search_options['value'];
									}
								} elseif ($field == 'status') {
									if ($search_options['value'] == 'all') {
										$this->params['named']['status'] = 'all';
									} else {
										$this->params['named']['status'] = $search_options['value'];
									}
								} else {
									if (isset($search_options['value']) && !empty($search_options['value'])) {
										if (!empty($prev_type_set)) {
											$new_condition .= ' '. strtoupper($prev_type). ' ';
											$prev_type_set = false;
										}
 
										if (isset($search_options['type']) && in_array(strtolower($search_options['type']), array('and', 'or'))) {
											$prev_type = strtoupper($search_options['type']);
											$prev_type_set = true;
										}

										$new_condition .= $this->_create_search_sql($search_options['value'], $field, $model);
									}
								}
								break;
							case 'CharactersHasProfile':
								if (isset($search_options['value']) && !empty($search_options['value'])) {
									$conditions['profile_search'] = true;

									if (!empty($prev_type_set)) {
										$new_condition .= ' '. strtoupper($prev_type). ' ';
										$prev_type_set = false;
									}
 
									if (isset($search_options['type']) && in_array(strtolower($search_options['type']), array('and', 'or'))) {
										$prev_type = strtoupper($search_options['type']);
										$prev_type_set = true;
									}

									$new_condition .= $this->_create_search_sql($search_options['value'], 'value', $model, $field);
								}
								break;
							default: 
								$this->Session->setFlash(__('Invalid Data.', true));
								$this->redirect(array('action'=>'index'));
								break;
						}
					}
				}
			}

			if (empty($isAdmin)) {
				if (!empty($new_condition)) {
					$new_condition = '('. $new_condition. ')';
				}
				if (isset($conditions['profile_search'])) {
					$new_condition .= ' AND';
					$new_condition .= ' CharactersHasProfile.public_flag = \'public\'';
				}
			}

			if (!empty($new_condition)) {
				$conditions['AND'][] = '('. $new_condition. ')';
			}
		}

		$this->_index($id, $conditions, $limit, array(), array(), array(), $page);
	}

	function _view($id, $conditions = array(), $isAdmin = false) {
		$this->helpers[] = 'CharacterSheet';

		// キャラデータ取得
		$orig_character = $this->_get_character($id, $conditions, $isAdmin);
		$character = $this->Character->set_profiles2view($orig_character);

		Configure::write('isOwner', false);
		if ($isAdmin || CorePlus::isOwner($character['Character'], $this->user_id)) {
			Configure::write('isOwner', true);
		}

		// Systemチェック
		$this->set('systemValid', 'public');
		if (!$character['System']) {
			$this->set('systemValid', false);
		}
		if (!$this->check_public_flag($character['System'])) {
			$this->set('systemValid', 'unpublic');
		}
/*		if ($character['System']['set_npc']) {
			$this->isNpc = true;
		}*/
		$character = $this->_restore_html_system($character);
		$character['System']['Profile'] = $this->_restore_html_characters_has_profiles($character['System']['Profile'], false);

		$this->set('title_for_layout', " - ". $character['Character']['name']);

		// キャラクターシート設定
		if (isset($this->params['named']['mode']) && !empty($this->params['named']['mode'])) {
			$mode = $this->params['named']['mode'];

			// スキン公開チェック
			$public_flg = false;
			$skin = array();
			if (!$isAdmin) {
				// 公開済み
				foreach ($character['System']['CharacterSheet'] as $v) {
					if ($v['key_name'] == $mode) {
						$public_flg = true;
						$skin = $v;
						break;
					}
				}

				// 自身のキャラシのみ
				if (!$public_flg) {
					$this->CharacterSheet = CorePlus::set_model('CharacterSheet');
					$characterSheet = $this->CharacterSheet->find('first', array(
						'conditions' => array('CharacterSheet.key_name' => $mode),
						'recursive' => -1,
					));

					if ($this->_checkCharaSheeOwner($characterSheet)) {
						$skin = $characterSheet['CharacterSheet'];
						$public_flg = true;
					}
				}
			} else {
				$public_flg = true;
			}
			if ($public_flg) {
				$this->view = 'Theme';
				$this->theme = $mode;

				$this->set('skin', $skin);
			}
		}

		return $character;
	} 

	function _delete($id = null, $conditions = array(), $isAdmin = false) {
		if (!$id) {
			$this->Session->setFlash(__('Invalid id for Character', true));
			$this->redirect(array('action'=>'index'));
		}

		$character = $this->_view($id, $conditions, $isAdmin);
		if (empty($character)) {
			$this->Session->setFlash(__('No Character', true));
			$this->redirect(array('action'=>'index'));
		}
		$this->set('character', $character);

		if (!$isAdmin && !$this->isOwner($character['Character'], $this->user_id)) {
			$this->Session->setFlash(__('No Permission', true));
			$this->redirect(array('action'=>'index'));
		}
		$this->set('isOwner', true);

		if (!empty($this->data)) {

			$this->data['clearCache'] = array(
				'character_id' => $id,
				'user_id' => $this->user_id,
				'system_id' => $character['System']['id'],
			);

			if ($this->data['Character']['confirm'] == 'yes') {
				// Character
				$this->data['Character']['id'] = $id;
				$this->data['Character']['main_picture'] = null;
				$this->data['Character']['full_length'] = null;
				$this->data['Character']['deleted'] = true;
				$this->data['Character']['deleted_date'] = date('Y-m-d H:i:s');

				$this->Character->create();
				if ($this->Character->save(
					$this->data,
					array(
						'validate' => false,
						'fieldList' => array(
							'main_picture',
							'full_length',
							'deleted',
							'deleted_date'
						),
					)
				)) {

					// CharactersHasProfiles
					$this->Character->CharactersHasProfile->updateAll(
						array(
							'CharactersHasProfile.public_flag' => "'private'",
						),
						array(
							'CharactersHasProfile.character_id' => $id
						)
					);

					// CharacterProfileArchives
					$date = date('Y-m-d H:i:s');
					$this->Character->CharacterProfileArchive->updateAll(
						array(
							'CharacterProfileArchive.deleted' => true,
							'CharacterProfileArchive.deleted_date' => "'$date'",
						),
						array(
							'CharacterProfileArchive.character_id' => $id
						)
					);

					// Attachments
					if (isset($character['CharacterPicture']) && !empty($character['CharacterPicture'])) {
						foreach ($character['CharacterPicture'] as $picture) {
							$this->Character->CharacterPicture->delete($picture['id']);
						}
					}

					$this->Session->setFlash(__('Character deleted', true));

					return true;
				} else {
					$this->Session->setFlash(__('The Character could not be deleted.', true));
				}
			}
		}

		return false;
	}

	/* 共通関数 */
	function _get_character($id, $conditions = array(), $isAdmin = false)
	{
		$character = $this->Character->get_character($id, $conditions, $isAdmin);

		if (empty($character)) {
			$this->Session->setFlash(__('No Character', true));
			$this->redirect(array('action'=>'index'));
		}

		if ($isAdmin === false && !$this->check_public_flag($character['Character'])) {
			$this->Session->setFlash(__('No Permission', true));
			$this->redirect(array('action'=>'index'));
		}

		if (isset($character['System']['Profile'])) {
			$character['System'] = $this->_restore_html_profile($character['System']);
		}

		return $character;
	}

	// ProfileTableをCharacterHasProfilesのTableの形式にセット
	function _set_profile_table2characters_has_profiles($profile)
	{
		if (!empty($profile[0]['CharactersHasProfile'])) {
			return $profile;
		}

		foreach($profile as $k => $v) {
			if (empty($v['ProfileTable'])) {
				continue;
			}

			$tmp = array();
			$rows = count($v['CharactersHasProfile']);
			for($i=0; $i<$rows; $i++) {
				foreach($v['ProfileTable'] as $k2 => $v2) {
					if (isset($v2['CharactersHasProfile'][$i])) {
						$tmp[] = $v2['CharactersHasProfile'][$i];
					} elseif (isset($v['CharactersHasProfile'][$i])) {
						$tmp[] = $v['CharactersHasProfile'][$i];
						break;

					} else {
						$tmp[] = null;
					}
				}
			}
			$profile[$k]['CharactersHasProfile'] = $tmp;

			if (isset($profile[$k]['ProfileTable'][0]['ProfileTableStatic']) && !empty($profile[$k]['ProfileTable'][0]['ProfileTableStatic'])) {
				$profile[$k]['ProfileTable'][0]['ProfileTableStatic'] = $this->_restore_html_profile_table_static($profile[$k]['ProfileTable'][0]['ProfileTableStatic']);
			}
		}

		return $profile;
	}
	// CharactersHasProfileの追加valiadte設定
	function _set_validate4characters_has_profile($system_id)
	{
		$this->Character->CharactersHasProfile->validate['profile_id']['validProfileId'] = array(
			'rule' => array('validProfileId', $system_id),
		);
		$this->Character->CharactersHasProfile->validate['profile_select_id']['validProfileSelectId'] = array(
			'rule' => array('validProfileSelectId', $system_id),
			'allowEmpty' => true,
		);
		$this->Character->CharactersHasProfile->validate['profile_table_id']['validProfiletableId'] = array(
		'rule' => array('validProfiletableId', $system_id),
		'allowEmpty' => true,
		);
	}

	/* restore_html */
	function _restore_html_character($data, $nl2br = false) {
		$data['name'] = $this->{$this->modelClass}->restore_html($data['name'], false, false, false);
		$data['notes'] = $this->{$this->modelClass}->restore_html($data['notes'], false, false, false);
		$data['secret_notes'] = $this->{$this->modelClass}->restore_html($data['secret_notes'], false, false, false);
		if ($nl2br) {
			$data['notes'] = str_replace('<br />', "\n", $data['notes']);
			$data['secret_notes'] = str_replace('<br />', "\n", $data['secret_notes']);
		}

		return $data;
	}

	function _restore_html_characters_has_profiles($profile, $nl2br = false) {
		if (empty($profile)) {
			return null;
		}

		foreach($profile as $k => $v) {
			if (empty($v['CharactersHasProfile'])) {
				continue;
			}
			$profile[$k]['CharactersHasProfile'] = $this->__restore_html_characters_has_profiles($v['CharactersHasProfile'], $nl2br, $v['profile_type']);
		}

		return $profile;
	}
	function __restore_html_characters_has_profiles($data, $nl2br = false, $profile_type = null) {
		if (empty($data)) {
			return null;
		}

		foreach ($data as $k => $v) {
			if (isset($v['value'])) {
				$data[$k]['value'] = $this->{$this->modelClass}->restore_html($v['value'], false, false, false);
				if ($nl2br && $profile_type == 'textarea') {
					$data[$k]['value'] = str_replace('<br />', "\n", $data[$k]['value']);
				}
			}
		}
		return $data;
	}

	function _checkRequiredProfile($profile)
	{
		if (empty($profile) || !isset($this->data['CharactersHasProfile'])) {
			return true;
		}

		$requireCheck = array();
		foreach($this->data['CharactersHasProfile'] as $k => $v) {
			if (!isset($requireCheck[$v['profile_id']])) {
				$requireCheck[$v['profile_id']] = null;
			}

			if (isset($requireCheck[$v['profile_id']]['value']) && !empty($requireCheck[$v['profile_id']]['value'])) {
				continue;
			}

			if (empty($v['value'])) {
				continue;
			}

			if (isset($v['profile_table_static_id']) && !empty($v['profile_table_static_id'])) {
				if (!isset($requireCheck[$v['profile_id']]['profile_table_id']) || empty($requireCheck[$v['profile_id']]['profile_table_id'])) {
					$requireCheck[$v['profile_id']]['profile_table_id'] = $v['profile_table_id'];
				}

				if ($requireCheck[$v['profile_id']]['profile_table_id'] == $v['profile_table_id']) {
					continue;
				}
			}

			$requireCheck[$v['profile_id']]['value'] = $v['value'];
		}

		$errors = array();
		foreach ($profile as $k => $v) {
			if ($v['required']) {
				if (!isset($requireCheck[$v['id']]) || empty($requireCheck[$v['id']]['value'])) {
					$errors[] = $v['name'];
				}
			}
		}

		if ($errors) {
			$this->Session->setFlash(sprintf(__('%s is required.', true), implode(',', $errors)));
			return false;
		} else {
			return true;
		}
	}

	function _create_search_sql($keywords, $field, $model, $profile_id = null)
	{
		$type = 'OR';
		$result = null;

		if (empty($keywords) || !is_string($keywords) || empty($field)) {
			return array();
		}

		if (!isset($this->search_cols[$model]) ||
			((empty($profile_id) && !array_key_exists($field, $this->search_cols[$model]))
			|| (!empty($profile_id) && !array_key_exists($profile_id, $this->search_cols[$model])))) {
			return null;
		}

		$keywords = rawurldecode($keywords);
		$searchwords = explode(",", $keywords);
		foreach ($searchwords as $k2 => $searchword) {
			if (empty($searchword)) {
				continue;
			}

			if (!empty($result)) {
				$result .= ' '. strtoupper($type). ' ';
			} else {
				$result .= '(';
			}

			$result .= '('. $model.'.'.$field. ' LIKE '. '\'%'. $searchword. '%\'';
			if (!empty($profile_id)) {
				$result .= ' AND CharactersHasProfile.profile_id = '. $profile_id;
			}
			$result .= ')';
		}
		$result .= ')';

		return $result;
	}

}
