<?php
if ( ! defined( 'ABSPATH' ) ) {
	die( 'You are not allowed to call this page directly.' );
}

/**
 * @since 2.03.05
 */
class FrmFieldFactory {

	/**
	 * Create an instance of an FrmFieldValueSelector object
	 *
	 * @since 2.03.05
	 *
	 * @param int   $field_id
	 * @param array $args
	 *
	 * @return FrmFieldValueSelector
	 */
	public static function create_field_value_selector( $field_id, $args ) {
		$selector = null;

		if ( $field_id > 0 ) {
			$selector = apply_filters( 'frm_create_field_value_selector', $selector, $field_id, $args );
		}

		if ( ! is_object( $selector ) ) {
			return new FrmFieldValueSelector( $field_id, $args );
		}

		return $selector;
	}

	/**
	 * @since 3.0
	 *
	 * @param array|object $field
	 *
	 * @return FrmFieldType
	 */
	public static function get_field_factory( $field ) {
		if ( is_object( $field ) ) {
			$field_info = self::get_field_object( $field );
		} elseif ( ! empty( $field['id'] ) ) {
			$field_info = self::get_field_object( $field['id'] );
		} else {
			$field_info = self::get_field_type( $field['type'], $field );
		}

		return $field_info;
	}

	/**
	 * @param int|object|string $field
	 *
	 * @return FrmFieldType
	 */
	public static function get_field_object( $field ) {
		if ( ! is_object( $field ) ) {
			$field = FrmField::getOne( $field );
		}

		return self::get_field_type( $field->type, $field );
	}

	/**
	 * @since 3.0
	 *
	 * @param string           $field_type
	 * @param array|int|object $field
	 *
	 * @return FrmFieldType
	 */
	public static function get_field_type( $field_type, $field = 0 ) {
		$class = self::get_field_type_class( $field_type );
		return $class ? new $class( $field, $field_type ) : new FrmFieldDefault( $field, $field_type );
	}

	/**
	 * @since 3.0
	 *
	 * @param string $field_type
	 *
	 * @return string
	 */
	private static function get_field_type_class( $field_type ) {
		$type_classes = array(
			'text'                         => 'FrmFieldText',
			'textarea'                     => 'FrmFieldTextarea',
			'select'                       => 'FrmFieldSelect',
			'radio'                        => 'FrmFieldRadio',
			'checkbox'                     => 'FrmFieldCheckbox',
			'number'                       => 'FrmFieldNumber',
			'phone'                        => 'FrmFieldPhone',
			'url'                          => 'FrmFieldUrl',
			'website'                      => 'FrmFieldUrl',
			'email'                        => 'FrmFieldEmail',
			'user_id'                      => 'FrmFieldUserID',
			'html'                         => 'FrmFieldHTML',
			'hidden'                       => 'FrmFieldHidden',
			'captcha'                      => 'FrmFieldCaptcha',
			'name'                         => 'FrmFieldName',
			'credit_card'                  => 'FrmFieldCreditCard',
			// Submit button field.
			FrmSubmitHelper::FIELD_TYPE    => 'FrmFieldSubmit',
			FrmFieldGdprHelper::FIELD_TYPE => FrmFieldGdprHelper::get_gdpr_field_class( $field_type ),
			'product'                      => 'FrmFieldProduct',
			'quantity'                     => 'FrmFieldQuantity',
			'total'                        => 'FrmFieldTotal',
		);

		$class = $type_classes[ $field_type ] ?? '';

		return apply_filters( 'frm_get_field_type_class', $class, $field_type );
	}

	/**
	 * @since 3.0
	 *
	 * @param string $type
	 *
	 * @return mixed
	 */
	public static function field_has_html( $type ) {
		$has_html = self::field_has_property( $type, 'has_html' );

		// This hook is here for reverse compatibility since 3.0
		return apply_filters( 'frm_show_custom_html', $has_html, $type );
	}

	/**
	 * @since 3.0
	 *
	 * @param string $type
	 * @param string $property
	 *
	 * @return mixed
	 */
	public static function field_has_property( $type, $property ) {
		$field = self::get_field_type( $type );
		return $field->{$property};
	}
}
