<?php

	class AjaxFormHelper extends kHelper {

		/**
		 * Sets error info as parameters in response object
		 * Expects that event status is not erSUCCESS
		 *
		 * @param kEvent $event
		 * @param Array $response
		 */
		public function prepareJSONErrors($event, &$response)
		{
			/** @var kDBItem $object */
			$object = $event->getObject();

			$response['status'] = 'FAILED';
			$response['field_errors'] = $this->getErrorMessages($object);
		}

		/**
		 * Returns object errors
		 *
		 * @param kDBItem $object
		 * @return Array
		 */
		public function getErrorMessages(&$object)
		{
			$error_msgs = Array ();
			$field_errors = array_keys( $object->GetFieldErrors() );

			foreach ($field_errors as $field) {
				if ( !$object->GetErrorPseudo($field) ) {
					continue;
				}

				if ( $object->GetFieldOption($field, 'formatter') == 'kMultiLanguage') {
					$field = 'l' . $this->Application->GetVar('m_lang') . '_' . $field;
				}

				$error_field = $object->GetFieldOption($field, 'error_field', false, $field);
				$error_msgs[$field] = $object->GetErrorMsg($error_field, false);
			}

			return $error_msgs;
		}

		/**
		 * Returns information about all uploader fields.
		 *
		 * @param kDBItem $object Object to process
		 * @param array|null $fields Fields filter.
		 *
		 * @return array
		 * @access public
		 */
		public function getUploaderInfo(kDBItem $object, $fields = null)
		{
			$ret = array();

			if ( !isset($fields) ) {
				$fields = array_keys($object->getFields());
			}

			foreach ($fields as $field) {
				$formatter = $object->GetFieldOption($field, 'formatter');

				if ( !$formatter ) {
					continue;
				}

				if ( $formatter == 'kUploadFormatter' || in_array('kUploadFormatter', class_parents($formatter)) ) {
					$ret[$field] = array(
						'urls' => $object->GetField($field, 'file_urls'),
						'names' => $object->GetField($field, 'file_names'),
						'sizes' => $object->GetField($field, 'file_sizes'),
					);
				}
			}

			return $ret;
		}

		/**
		 * Sends JSON-encoded response as event result to the browser
		 *
		 * @param kEvent $event
		 * @param Array $response
		 */
		public function sendResponse($event, $response = Array ())
		{
			if ( !isset($response['status']) ) {
				$response['status'] = 'OK';
			}

			/** @var JSONHelper $json_helper */
			$json_helper = $this->Application->recallObject('JSONHelper');

			echo $json_helper->encode($response);

			$event->status = kEvent::erSTOP;
		}

		/**
		 * Calls given event and returns nice JSON output
		 *
		 * @param kEvent $event
		 * @param string $call_event
		 * @param Array $params
		 * @param Closure $callback
		 * @return bool
		 * @access public
		 */
		public function transitEvent($event, $call_event, $params = Array (), $callback = null)
		{
			$params['status'] = 'OK';
			$event->CallSubEvent($call_event);

			$form_data = $event->getEventParam('form_data');

			if ( $form_data !== false ) {
				/** @var kDBItem $object */
				$object = $event->getObject();

				$params['uploader_info'] = $this->getUploaderInfo($object, array_keys($form_data));
			}

			if ( is_callable($callback) ) {
				call_user_func($callback, $event);
			}

			if ( $event->status != kEvent::erSUCCESS ) {
				$this->prepareJSONErrors($event, $params);
			}
			else {
				if ( !isset($params['redirect_to']) && ($event->redirect === true || strlen($event->redirect) > 0) ) {
					if ( $event->redirect === true ) {
						$event->redirect = '';
					}

					$params['redirect_to'] = $this->Application->HREF($event->redirect, '', $event->getRedirectParams(), $event->redirectScript);
				}

				$params = array_merge($params, $event->getRedirectParams());
			}

			$this->sendResponse($event, $params);

			return $params['status'] == 'OK';
		}
	}
