<?php

abstract class ScaffoldCtrl extends Ctrl {



	abstract protected function buildModel($id = null);



	abstract protected function buildForm($id = null);



	protected function buildTranslator($id = null) {
		return new CompositeTranslator();
	}



	protected function buildValidator(Form $f, FormContext $cx) {
		return new CompositeValidator();
	}



	public function create() {
		$form = $this->buildForm();
		if (!($form instanceof Form)) {
			throw new Exception(get_class($this) . '::buildForm must return Form');
		}
		return $form;
	}



	public function edit($id) {
		// build Translator
		$translator = $this->buildTranslator($id);
		if (!($translator instanceof CompositeTranslator)) {
			throw new Exception(get_class($this) . '::buildTranslator must return CompositeTranslator');
		}
		// build model
		$ar = $this->buildModel($id);
		if (!($ar instanceof ActiveRecord)) {
			throw new Exception(get_class($this) . '::buildModel must return ActiveRecord');
		}
		// build Form
		$form = $this->buildForm($id);
		if (!($form instanceof Form)) {
			throw new Exception(get_class($this) . '::buildForm must return Form');
		}
		// push model into Form
		foreach ($translator->mtov($ar->getIterator()) as $field => $value) {
			if ($view = &$form->getChildById($field)) {
				$view->value = $value;
			}
		}
		return $form;
	}



	public function save(FormContext $cx, $id = null) {
		// build Form
		$form = $this->buildForm();
		if (!($form instanceof Form)) {
			throw new Exception(get_class($this) . '::buildForm must return Form');
		}
		// build Validator
		$validator = $this->buildValidator($form, $cx);
		if (!($validator instanceof IValidator)) {
			throw new Excpetion(get_class($this) . '::buildValidator must return IValidator');
		}
		if (!$validator->valid()) {
			return;
		}
		// build Translator
		$translator = $this->buildTranslator($id);
		if (!($translator instanceof CompositeTranslator)) {
			throw new Exception(get_class($this) . '::buildTranslator must return CompositeTranslator');
		}
		// build model
		$ar = $this->buildModel($id);
		if (!($ar instanceof ActiveRecord)) {
			throw new Exception(get_class($this) . '::buildModel must return ActiveRecord');
		}
		// push data from FormContext back to model
		foreach ($translator->vtom($cx) as $field => $value) {
			$ar->$field = $value;
		}
		$ar->save();
	}



	public function delete($id, $soft) {

	}



	public function undelete($id) {

	}



} // class ScaffoldCtrl

?>