<?php
/*
 * Copyright (c) 2013, webvariants GbR, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 */

/**
 * @ingroup datatypes
 */
class _WV_Datatype_Repeat extends _WV_Datatype_Base implements WV_IDatatype {
	public function renderForm(sly_Form $form, WV_IProperty $property, $value) {
		$params    = $property->getParams();
		$propID    = $property->getID();
		$title     = $property->getTitle();
		$name      = 'property_' . $propID . '_value';
		$value     = $this->decodeFormValue($property, $value);
		$value     = json_decode($value, true);
		$params    = $this->deserializeParams($params);
		$multi     = new WV_Form_Repeat($name, $title, $property->getType(), $property->getName());
		$fake_form = new _WV_Datatype_Repeat_FakeForm($multi);

		if (empty($value)) {
			$value = array(array());
		}

		foreach ($value as $group => $v) {
			if (!is_array($v)) {
				$v = array();
			}

			foreach ($params['children'] as $childName => $child) {
				$property2 = new _WV2_Info($property->getType(), $name . '_' . $childName . '_' . $group, array(
					'title'    => $child['title'],
					'datatype' => $child['datatype'],
					'params'   => array_key_exists('params', $child) ? $child['params'] : array(),
					'backend'  => array_key_exists('backend', $child) ? $child['backend'] : true
				));

				$datatype = WV_Datatype::factory($child['datatype']);
				$multi->setLabelAttr(array_key_exists('label_attr', $child) ? $child['label_attr'] : null);
				$multi->setLabelStyle(array_key_exists('label_style', $child) ? $child['label_style'] : null);
				$multi->setNewline(array_key_exists('newline', $child) ? $child['newline'] : null);

				if (!$property2->getBackend()) {
					$multi->hideStart();
				}

				$datatype->renderForm($fake_form, $property2, array(array_key_exists($childName, $v) ? $v[$childName] : ''));

				if (!$property2->getBackend()) {
					$multi->hideEnd();
				}
			}

			$fake_form->add($hidden = new sly_Form_Input_Text('property_' . $propID . '_value[]', null, $group));
			$hidden->setAttribute('type', 'hidden');
			$hidden->setAttribute('class', 'form-repeat-group');
			$multi->nextGroup();
		}

		$form->add($multi);

		return $form;
	}

	protected function getDefaultParams() {
		return array('children' => array());
	}

	public function serializeValue($values, array $params) {
		if (!is_array($values)) {
			$values = array();
		}

		$ret = array();

		foreach ($values as $group_values) {
			if (!is_array($group_values)) continue;
			$ret_group = array();

			foreach ($params['children'] as $childName => $child) {
				$value    = array_key_exists($childName, $group_values) ? $group_values[$childName] : null;
				$datatype = WV_Datatype::factory($child['datatype']);

				$ret_group[$childName] = $datatype->serializeValue($value, array_key_exists('params', $child) ? $child['params'] : array());
			}

			$ret[] = $ret_group;
		}

		return json_encode($ret);
	}

	public function deserializeValue($value, array $params) {
		$values = json_decode($value, true);

		if (!is_array($values)) {
			$values = array();
		}

		$ret = array();

		foreach ($values as $group_values) {
			$ret_group = array();

			foreach ($params['children'] as $childName => $child) {
				$value    = array_key_exists($childName, $group_values) ? $group_values[$childName] : '';
				$datatype = WV_Datatype::factory($child['datatype']);

				$ret_group[$childName] = $datatype->deserializeValue($value, array_key_exists('params', $child) ? $child['params'] : array());
			}

			$ret[] = $ret_group;
		}

		return $ret;
	}

	public function isValueContained($valueToSearch, $valueFromDatabase, array $params, $operator) {
		throw new WV_Exception_Datatype('not yet implemented');
	}

	public function serializeFormFilter($list, WV_IProperty $property) {
		$params = $property->getParams();
		$propID = $property->getID();
		$title  = $property->getTitle();
		$name   = 'property_' . $propID . '_value';
		$groups = sly_post('property_' . $propID . '_value', 'array');

		foreach ($list as $clangID => $values) {
			$values  = sly_makeArray($values);
			$values  = array_values($values);
			$collect = array();

			if (is_array($groups)) {
				foreach ($groups as $group) {
					$group_data = array();

					foreach ($params['children'] as $childName => $child) {
						$property2 = new _WV2_Info($property->getType(), $name . '_' . $childName . '_' . $group, array(
							'title'    => $child['title'],
							'datatype' => $child['datatype'],
							'params'   => array_key_exists('params', $child) ? $child['params'] : array(),
							'backend'  => array_key_exists('backend', $child) ? $child['backend'] : true
						));

						$datatype = WV_Datatype::factory($child['datatype']);
						$group_data[$childName] = $datatype->serializeForm($property2);
					}

					$collect[] = $group_data;
				}
			}

			$list[$clangID] = json_encode($collect);
		}

		return $list;
	}

	public static function addRowMarkup($type, $name, $group) {
		$property = WV2_Metainfo::getMetainfo($name, $type);
		$params   = $property->getParams();
		$propID   = $property->getID();
		$title    = $property->getTitle();
		$name     = 'property_'.$propID.'_value';

		$multi     = new WV_Form_Repeat($property->getName(), $title);
		$fake_form = new _WV_Datatype_Repeat_FakeForm($multi);

		$default_value = self::getNewLine($property);

		foreach ($params['children'] as $childName => $child) {
			$property2 = new _WV2_Info($property->getType(), $name . '_' . $childName . '_' . $group, array(
				'title'    => $child['title'],
				'datatype' => $child['datatype'],
				'params'   => array_key_exists('params', $child) ? $child['params'] : array(),
			));

			$datatype = WV_Datatype::factory($child['datatype']);
			$multi->setLabelAttr(array_key_exists('label_attr', $child) ? $child['label_attr'] : null);
			$multi->setLabelStyle(array_key_exists('label_style', $child) ? $child['label_style'] : null);
			$multi->setNewline(array_key_exists('newline', $child) ? $child['newline'] : null);

			$value = '';

			if (isset($default_value[$childName])) {
				$value = is_array($default_value[$childName]) ? reset(array_keys($default_value[$childName])) : $default_value[$childName];
			}

			if (!$property2->getBackend()) {
				$multi->hideStart();
			}
			$datatype->renderForm($fake_form, $property2, array($value));
			if (!$property2->getBackend()) {
				$multi->hideEnd();
			}
		}

		$fake_form->add($hidden = new sly_Form_Input_Text('property_'.$property->getID().'_value[]', null, $group));
		$hidden->setAttribute('type', 'hidden');
		$hidden->setAttribute('class', 'form-repeat-group');

		return $multi->renderGroup();
	}

	protected static function getNewLine(WV_IProperty $property) {
		$default_value = array();
		$params        = $property->getParams();

		foreach ($params['children'] as $childName => $child) {
			$default_value[$childName] = isset($child['default']) ? $child['default'] : null;
		}

		return $default_value;
	}

	public function getDefaultValue(WV_IProperty $property) {
		return $this->serializeValue(array(self::getNewLine($property)), $property->getParams());
	}
}
