<?php
/**
 * Created by PhpStorm.
 * User: proess
 * Date: 2/06/23
 * Time: 16:20 PM
 */

namespace IMATHUZH\Qfq\Core\Form;

use CodeException;
use DbException;
use IMATHUZH\Qfq\Core\Form\FormElement\AbstractFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\AiChatFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\AnnotateFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\ChatFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\CheckboxFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\ColorPickerFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\DatetimeFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\EditorFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\ExtraFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\FieldsetFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\ImageCutFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\InputFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\InputCollectionJsonFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\NoteFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\PillFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\RadioButtonFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\SelectFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\SubrecordFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\TemplateGroupFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\UploadFormElement;
use UserFormException;
use UserReportException;

/**
 * Class FeFactory
 * @package qfq
 */
class FeFactory {

    /**
     * Creates and returns an instance of a concrete class that extends the AbstractFormElement class, based on the given feType.
     *
     * @param string $formElementSpec The record ID.
     * @param ?Form $form Object representing the form, to which the FormElement belongs. Can be null, i.e. for inline-edit elements.
     * @return AbstractFormElement Instance of concrete FormElement class.
     * @throws CodeException
     * @throws UserReportException
     * @throws DbException
     *
     * @throws UserFormException
     */
    public static function createFormElement(array $formElementSpec, ?Form $form): AbstractFormElement {
        $feType = $formElementSpec['type'];
        $formElement = null;

        switch ($feType) {
            case FE_TYPE_PILL:
                $formElement = new PillFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_FIELDSET:
                $formElement = new FieldsetFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_TEMPLATE_GROUP:
                $formElement = new TemplateGroupFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_TEXT:
            case FE_TYPE_PASSWORD:
                $formElement = new InputFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_SUBRECORD:
                $formElement = new SubrecordFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_CHECKBOX:
                $formElement = new CheckboxFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_RADIO:
                $formElement = new RadioButtonFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_SELECT:
                $formElement = new SelectFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_NOTE:
                $formElement = new NoteFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_EDITOR:
                $formElement = new EditorFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_DATETIME:
            case FE_TYPE_DATE:
            case FE_TYPE_TIME:
                $formElement = new DatetimeFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_UPLOAD:
                $formElement = new UploadFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_IMAGE_CUT:
                $formElement = new ImageCutFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_ANNOTATE:
                $formElement = new AnnotateFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_EXTRA:
                $formElement = new ExtraFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_CHAT:
                $formElement = new ChatFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_AI_CHAT:
                $formElement = new AiChatFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_COLOR_PICKER:
                $formElement = new ColorPickerFormElement($formElementSpec, $form);
                break;
            case FE_TYPE_INPUT_COLLECTION_JSON:
                $formElement = new InputCollectionJsonFormElement($formElementSpec, $form);
                break;
            default:
                throw new UserFormException("No class exists for feType: " . $feType);
        }
        return $formElement;
    }

}
