<?php
App::import('Model', 'Dictionary');
class Content extends AppModel {
	public $name = 'Content';

	public $belongsTo = array(
		'Template'
	);

	public $hasMany = array(
		'Blocks' => array(
			'className' => 'Block'
		)
	);

	public $order = array(
		'Content.position' => ASC
	);


# ~ Get sections - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function getContent($model, $fkey, $field = 'content', $locale = null, $full = null) {

		# Get all or just active locale
		if($locale === null) {
			setDefault($full, CMS);
			$locale = CMS ? array_keys(Configure::read('Config.Languages')) : Configure::read('Config.language');
		}

		# Get content
		$contents = $this->find('all', array(
			'Get content for the page',
			'conditions' => array(
				'Content.model' => $model,
				'Content.foreign_key' => $fkey,
				'Content.field' => $field,
				'Content.locale' => $locale),
			'contain' => array(
				'Blocks.id', 'Blocks.name', 'Blocks.content_id', 'Blocks.content',
				'Template.id', 'Template.name', 'Template.description', 'Template.body', 'Template.stylesheet_set', 'Template.javascript_set')
		));

		# Pack and return the content
		$packed = $this->packContent($contents, $model);
		return $full ? $packed : $packed[$locale];
	}


# ~ Pack contents from supplied set of data	 - - - - - - - - - - - - - - - - - #
	public function packContent($contents, $model) {

		# Pack the content by languages
		foreach(Configure::read('Config.Languages') as $locale => $language) {
			$contents[$locale] = array('Body' => '', 'stylesheet_set' => '', 'javascript_set' => '');
		}
		foreach($contents as $i => $content) if(is_numeric($i)) {
			unset($contents[$i]);

			# Repack the block
			foreach($content['Blocks'] as $i => $block) if(is_numeric($i)) {
				unset($content['Blocks'][$i]);
				$content['Blocks'][$block['name']] = $block;
			}

			# Insert the blocks
			$this->Template->set($content['Template']);
			$content['Content']['content'] = $this->Template->insertBlocks($content['Blocks']);
			$content['Template'] = $this->Template->data['Template'];

			# Handle non-polygot views
			if(strpos($content['Template']['name'], '  ') !== FALSE) {
				$polyglotSkip = mt_rand();
				$content['Content']['content'] =
					"<!-- " . Dictionary::POLYGLOT_SKIP_START . "_{$polyglotSkip} -->" .
					$content['Content']['content'] .
					"<!-- " . Dictionary::POLYGLOT_SKIP_END . "_{$polyglotSkip} -->";
			}

			# Add missing blocks
			foreach($content['Template']['fields'] as $name => $type) {
				initKey($content['Blocks'], $name, array('id' => null, 'name' => $name, 'content' => '', 'content_id' => $content['Content']['id']));
				$content['Blocks'][$name]['type'] = $type;
			}

			# Update the body
			$contents[$content['Content']['locale']]['Body'] .= $content['Content']['content'];
			$contents[$content['Content']['locale']][] = $content;

			# Update the sets
			foreach(array('stylesheet', 'javascript') as $set) {
				$set = "{$set}_set";
				$prev = $contents[$content['Content']['locale']][$set];
				$more = isset($content['Template'][$set]) ? $content['Template'][$set] : null;
				if($more) {
					$contents[$content['Content']['locale']][$set] = mergeSets($contents[$content['Content']['locale']][$set], $content['Template'][$set]);
				}

			}
		}

		return $contents;
	}


# ~ Prepares the content for insert upon saving the object - - - - - - - - - - #
	public function prepare(&$data, $model = null) {
		setDefault($model, key($data));

		$preparedContent = array();

		# Get the list of fields
		$fields = array_unique(array_pop($data['Content']));

		# Create save array
		$save = array();
		foreach($data['Content'] as $i => $content) {
			$position[$content['locale']] = isset($position[$content['locale']]) ? $position[$content['locale']]+1 : 1;

			# Relate to parent
			$content['model'] = $model;
			$content['position'] = $position[$content['locale']];
			$content['foreign_key'] = $data[$model]['id'];

			# Blocks
			$blocks = array();
			if(!empty($content['Blocks'])) {
				foreach($content['Blocks'] as $name => $value) {
					$blocks[] = array(
						'id' => null,
						'name' => $name,
						'content' => $value
					);
				}
			}
			unset($content['Blocks']);

			# Append to save array
			$saveAll = array('Content' => $content, 'Blocks' => $blocks);
			$preparedContent[] = $saveAll;

			# Validate
			$this->set($saveAll);
			if(!$this->validates()) {
				return false;
			}
		}

		# Append templates
		$list = Set::extract('/Content/template_id', $preparedContent);
		$templates = $this->Template->find('all', array(
			'Get all used templates',
			'pack' => true,
			'recursive' => -1,
			'fields' => array('Template.id', 'Template.name', 'Template.body'),
			'conditions' => array('Template.id' => array_unique($list))
		));
		foreach($preparedContent as $i => $content) {
			$preparedContent[$i]['Template'] = $templates[$content['Content']['template_id']]['Template'];
		}

		# Cache the fields
		$pack = $this->packContent($preparedContent, $model);
		$data = $this->updateFields($pack, $data, $fields, $model);

		return $preparedContent;
	}


# ~ Inserts the content	 - - - - - - - - - - - - - - - - - - - - - - - - - - - #
	public function insert($content, $data, $model = null) {
		setDefault($model, key($data));

		$this->BEGIN();

		# Remove all previous content
		$fields = array_unique(Set::extract('/Content/field',$content));
		if(!empty($fields)) {
			$this->deleteAll(array(
				'Content.model' => $model,
				'Content.foreign_key' => $data[$model]['id'],
				'Content.field' => $fields
			));
		}

		# Refresh all contents, delete first to delete all blocks as well
		foreach($content as $record) {
			unset($record['Template']);
			$record['Content']['foreign_key'] = $data[$model]['id'];
			$this->set($record);
			$this->delete();

			# Unset if no block supplied
			if(empty($record['Blocks'])) {
				unset($record['Blocks']);
			}

			$this->saveAll($record);
		}

		$this->COMMIT;
	}


# ~ Updates fields in the data based on the content	 - - - - - - - - - - - - - #
	public function updateFields($content = null, $data, $fields, $model = null) {
		setDefault($model, key($data));

		# Get content
		foreach($fields as $field) {

			# Read content from the database
			if($content === null) {
				$content = $this->getContent($model, $data[$model]['id'], $field);
			}

			# Change the values
			foreach($content as $locale => $body) {
				$value = '';
				foreach($body as $i => $item) if(is_numeric($i)) {
					$this->Template->set($item);
					$value .= $this->Template->insertBlocks($item['Blocks'], false);
				}

				$data[$model]["{$field}__{$locale}"] = $value;
			}
		}

		return $data;
	}

}
