<?php

/**
 * @package     Joomla.Site
 * @subpackage  com_formea
 *
 * @copyright   Copyright (C) 2010-2025 Feseur Sdn Bhd. All rights reserved.
 * @license     GNU General Public License version 2 or later; see LICENSE.txt
 * @version     1.3.0
 */

namespace Joomla\Component\Formea\Site\Libraries;

defined('_JEXEC') or die;

use Exception;
use Feseur\Library\FsrResponse;
use Joomla\CMS\Factory;
use Joomla\CMS\Helper\UserGroupsHelper;
use Joomla\CMS\Language\Text;
use Joomla\Component\Formea\Administrator\Helper\FormeaHelper;
use Joomla\Component\Formea\Site\Helper\FormeaGeneralHelper;
use Joomla\Database\DatabaseDriver;
use Joomla\Filesystem\Path;
use Joomla\Registry\Registry;
use ReflectionObject;
use ReflectionProperty;

class FormeaElement
{
	/**
	 * @var int
	 * @since 1.0.0
	 */
	protected $element_id;
	protected $element_type = null;
	public $id = 0;
	public $title = null;
	public $alias = null;
	public $type = null;
	public $state = null;
	public $params = null;
	public $checked_out = null;
	public $checked_out_time = null;
	public $created_date = null;
	public $modified_date = null;
	public $modified_by = null;
	public $created_by = null;
	public $access_level = null;
	public $publish_up = null;
	public $publish_down = null;
	public $attributes = null;
	public $details = null;
	public $elementvalues = null;
	public $validations = null;
	public $preview = null;
	public $previewBare = null;
	public $labelSettings = null;
	public $elementTypeConfig = null;
	protected $langTag;
	protected $langTagUnderscore;
	protected $languages;
	protected $elementTypeClass;
	protected $langData;
	public $form_id = 0;
	public $imageDetails;
	public $previewSettings;

	/**
	 * @var string
	 * @since 1.0.0
	 */
	public $elementTypeTitle = '';

	/**
	 * @var int
	 * @since 1.0.0
	 */
	public $value_type = -2;

	/**
	 * @var int
	 * @since 1.0.0
	 */
	public $elementTypeId = 0;

	/**
	 * @var bool
	 * @since 1.0.0
	 */
	private $isPreview = true;

	/**
	 * @var string
	 * @since 1.0.0
	 */
	public $formUniqueString;

	public $isGroup = false;
	public $group_id = -1;
	public $group_type = -1;
	public $setIndex = 0;

	/**
	 * @var Registry | null
	 * @since 1.0.5
	 */
	public $form_element_settings = null;

	/**
	 * @var FormeaCore[]
	 * @since 1.0.3
	 */
	protected $coreClasses;

	/**
	 * @var FormeaValidation[] | null
	 * @since 1.0.3
	 */
	public $validationClasses = null;

	/**
	 * Input group setting
	 * @var array
	 * @since 1.0.3
	 */
	public $igSetting;

	/**
	 * @var FormeaTheme
	 * @since 1.0.0
	 */
	protected $themeClass;

	public function __construct($config = [])
	{
		if (isset($config['igSetting'])) {
			$this->igSetting = $config['igSetting'];
		} else {
			$this->igSetting = [
				'bare' => false
			];
		}
		if (isset($config['form_element_settings'])) {
			$this->form_element_settings = $config['form_element_settings'];
		}
		if (isset($config['themeClass'])) {
			$this->themeClass = $config['themeClass'];
		}
		if (isset($config['form_id'])) {
			$this->form_id = $config['form_id'];
		}
		if (isset($config['element_id'])) {
			$this->element_id = $config['element_id'];
		} else {
			$this->element_id = 0;
		}
		if (isset($config['is_preview'])) {
			$this->isPreview = filter_var($config['is_preview'], FILTER_VALIDATE_BOOLEAN);
		}

		if ($this->element_id > 0) {
			$app                     = Factory::getApplication();
			$this->langTag           = $app->getLanguage()->getTag();
			$this->langTagUnderscore = str_replace('-', '_', $this->langTag);
			$this->languages         = FormeaGeneralHelper::getLanguages();
		}

		if (isset($config['formUniqueString'])) {
			$this->formUniqueString = $config['formUniqueString'];
		}

		if (isset($config['isGroup'])) {
			$this->isGroup = $config['isGroup'];
		} else {
			$this->isGroup = false;
		}
		if (isset($config['group_id'])) {
			$this->group_id = $config['group_id'];
		}
		if (isset($config['group_type'])) {
			$this->group_type = $config['group_type'];
		}
		if (isset($config['setIndex'])) {
			$this->setIndex = $config['setIndex'];
		}

		if (isset($config['coreClasses'])) {
			$this->coreClasses = $config['coreClasses'];
		} else {
			$this->coreClasses = [new FormeaCore()];
		}
	}

	public function getElement()
	{
		$container = Factory::getContainer();
		/** @var DatabaseDriver $db */
		$db = $container->get('DatabaseDriver');
		if ($this->element_id > 0) {

			$where = $db->quoteName('id') . ' = ' . $this->element_id;
			$query = $db->getQuery(true);
			$query->select('*');
			$query->from($db->quoteName('#__formea_elements'));
			$query->where($where);
			$db->setQuery($query);
			$ret = $db->loadObject();
			if (!empty($ret)) {
				$ret->params = new Registry($ret->params);
				$fields      = $this->getAvailableFields();
				if (!empty($fields)) {
					$totalFields = count($fields);
					for ($i = 0; $i < $totalFields; $i++) {
						if (isset($ret->{$fields[$i]})) {
							$this->{$fields[$i]} = $ret->{$fields[$i]};
						}
					}
				}
			}
		}
		if ($this->id == 0) {
			$u      = UserGroupsHelper::getInstance();
			$ug     = $u->getAll();
			$ug     = array_keys($ug);
			$t      = (object) [
				'title'            => '',
				'alias'            => '',
				'state'            => 1,
				'checked_out'      => '',
				'checked_out_time' => '',
				'created_date'     => '',
				'modified_date'    => '',
				'modified_by'      => 0,
				'created_by'       => 0,
				'access_level'     => $ug[0],
				'publish_up'       => '',
				'publish_down'     => '',
			];
			$fields = $this->getAvailableFields();
			if (!empty($fields)) {
				$totalFields = count($fields);
				for ($i = 0; $i < $totalFields; $i++) {
					if (isset($t->{$fields[$i]})) {
						$this->{$fields[$i]} = $t->{$fields[$i]};
					}
				}
			}
		}

		return $this;
	}

	protected function _getValidationClasses()
	{
		$container = Factory::getContainer();
		/** @var DatabaseDriver $db */
		$db    = $container->get('DatabaseDriver');
		$query = $db->getQuery(true);
		$query->select(['a.*', 'b.params AS validation_params', 'b.id AS validation_id']);
		$query->from($db->quoteName('#__formea_element_validations', 'a'))
			->innerJoin(
				$db->quoteName('#__formea_validations', 'b') . ' ON ' . $db->quoteName('a.validation_type')
					. ' = ' . $db->quoteName('b.name')
			);
		$query->where($db->quoteName('a.element_id') . ' = ' . $db->quote($this->id));
		$query->order('a.id ASC');
		$db->setQuery($query);
		$validations = $db->loadObjectList();
		if (!empty($validations)) {
			$totalValidations = count($validations);
			for ($i = 0; $i < $totalValidations; $i++) {
				if (is_file(Path::clean(FORMEA_VALIDATION_PATH . '/' . $validations[$i]->validation_type . '/' . $validations[$i]->validation_type . '.php'))) {
					$validation_params = '[]';
					if (!empty($validations[$i]->validation_params)) {
						$validation_params = json_decode($validations[$i]->validation_params);
					}
					$validation_params = new Registry($validation_params);
					require_once FORMEA_VALIDATION_PATH . '/' . $validations[$i]->validation_type . '/' . $validations[$i]->validation_type . '.php';
					$clsName                                       = $validations[$i]->validation_type;
					$validationClass                               = new $clsName([
						'id'     => $validations[$i]->validation_id,
						'params' => $validation_params,
					]);
					$this->validationClasses[$validations[$i]->id] = $validationClass;
				}
			}
		}
	}

	public function getValidationClasses()
	{
		if (is_null($this->validationClasses)) {
			$this->_getValidationClasses();
		}

		return $this->validationClasses;
	}

	/**
	 * Get element attribute values
	 *
	 * @param   bool  $formatted
	 *
	 * @return FormeaElementAttribute|null
	 *
	 * @since 1.0.0
	 */
	public function getAttributes(bool $formatted = true)
	{
		$ret = null;
		if (is_null($this->attributes)) {
			if ($this->element_id > 0) {
				if (empty($this->attributes)) {
					$attribute        = new FormeaElementAttribute(['element_id' => $this->element_id]);
					$this->attributes = $attribute->getAttributes($formatted);
				}
				$ret = $this->attributes;
			} else {
				$attribute        = new FormeaElementAttribute();
				$this->attributes = $attribute->getAttributes($formatted);
			}
		}


		return $ret;
	}

	/**
	 * Get element details
	 *
	 * @param   bool  $formatted  False will return raw data from db
	 *
	 * @return array  Formatted: [lang_code_underscore => [caption=>string, placeholder=>string, description=>string]]
	 *
	 * @since 1.0.0
	 */
	public function getDetails(bool $formatted = true, bool $force = false)
	{
		$ret = [];
		if (empty($this->details) || $force) {
			if ($this->element_id > 0) {
				$columns = [
					'caption',
					'placeholder',
					'description',
					'language',
				];
				if (!$formatted) {
					$columns = '*';
				}
				$container = Factory::getContainer();
				/** @var DatabaseDriver $db */
				$db    = $container->get('DatabaseDriver');
				$query = $db->getQuery(true);
				$query->select($columns);
				$query->from($db->quoteName('#__formea_element_details'));
				$query->where($db->quoteName('element_id') . ' = ' . $this->element_id);
				$query->order('id ASC');
				$db->setQuery($query);
				$results = $db->loadObjectList();

				if (!empty($results) && $formatted) {
					// $languages         = FormeaGeneralHelper::getLanguages();
					//$langTag           = $this->langTag;
					$langTagUnderscore = $this->langTagUnderscore;
					$totalResults      = count($results);
					$primaryLang       = [];
					for ($i = 0; $i < $totalResults; $i++) {
						$langUnderscore = str_replace('-', '_', $results[$i]->language);
						if ($langUnderscore !== $langTagUnderscore) {
							$ret[$langUnderscore] = [
								'caption'     => $results[$i]->caption,
								'placeholder' => $results[$i]->placeholder,
								'description' => $results[$i]->description,
							];
						} else {
							//primary
							$primaryLang[$langUnderscore] = [
								'caption'     => $results[$i]->caption,
								'placeholder' => $results[$i]->placeholder,
								'description' => $results[$i]->description,
							];
						}
					}
					if (!empty($primaryLang)) {
						//$arr1 = array('key0' => 'value0') + $arr1;
						$ret = $primaryLang + $ret;
					}
				} else {
					$ret = $results;
				}
				$this->set('details', $ret);
			} else {
				$langData  = $this->_getLangData();
				$totalLang = count($langData);
				for ($i = 0; $i < $totalLang; $i++) {
					$defObject = FormeaHelper::commonElementDetailArray($langData[$i]);
					if (!empty($defObject)) {
						$ret[$langData[$i]] = $defObject[$langData[$i]];
					}
				}
				$this->set('details', $ret);
			}
		}

		return $ret;
	}

	/**
	 * Get element values
	 *
	 * @param   bool  $formatted  False will return raw data from db
	 *
	 * @return array  Formatted: [lang_code_underscore => [defval=>string, option_lists=>OptionTextVal[]]]
	 *
	 * @since 1.0.0
	 */
	public function getValues(bool $formatted = true, bool $force = false)
	{
		$ret = [];
		if (empty($this->elementvalues) || $force) {
			if ($this->element_id > 0) {
				$columns = [
					'defval',
					'option_lists',
					'language',
				];
				if (!$formatted) {
					$columns = '*';
				}
				$container = Factory::getContainer();
				/** @var DatabaseDriver $db */
				$db    = $container->get('DatabaseDriver');
				$query = $db->getQuery(true);
				$query->select($columns);
				$query->from($db->quoteName('#__formea_element_values'));
				$query->where($db->quoteName('element_id') . ' = ' . $this->element_id);
				$query->order('id ASC');
				$db->setQuery($query);
				$results = $db->loadObjectList();
				if (!empty($results) && $formatted) {
					// $languages         = FormeaGeneralHelper::getLanguages();
					$langTag           = $this->langTag;
					$langTagUnderscore = $this->langTagUnderscore;
					$totalResults      = count($results);
					$primaryLang       = [];
					for ($i = 0; $i < $totalResults; $i++) {
						$optionLists = [];
						if (!empty($results[$i]->option_lists)) {
							$optionLists = json_decode($results[$i]->option_lists);
							if (is_array($optionLists)) {
								$totalOptionLists = count($optionLists);
								for ($o = 0; $o < $totalOptionLists; $o++) {
									$optionLists[$o]->selected = filter_var($optionLists[$o]->selected, FILTER_VALIDATE_BOOLEAN);
								}
							}
						}
						$langUnderscore = str_replace('-', '_', $results[$i]->language);
						if ($langUnderscore !== $langTagUnderscore) {
							$ret[$langUnderscore] = [
								'defval'       => $results[$i]->defval,
								'option_lists' => $optionLists
							];
						} else {
							//primary
							$primaryLang[$langUnderscore] = [
								'defval'       => $results[$i]->defval,
								'option_lists' => $optionLists
							];
						}
					}
					if (!empty($primaryLang)) {
						//$arr1 = array('key0' => 'value0') + $arr1;
						$ret = $primaryLang + $ret;
					}
				} else {
					$ret = $results;
				}
				$this->elementvalues = $ret;
			} else {
				$langData  = $this->_getLangData();
				$totalLang = count($langData);
				for ($i = 0; $i < $totalLang; $i++) {
					$defObject = FormeaHelper::commonElementValueArray($langData[$i]);
					if (!empty($defObject)) {
						$ret[$langData[$i]] = $defObject[$langData[$i]];
					}
				}
				$this->elementvalues = $ret;
			}
		}


		return $ret;
	}

	/**
	 * Get element values
	 *
	 * @param   bool  $formatted  False will return raw data from db
	 *
	 * @return array  Formatted: [lang_code_underscore => [defval=>string, option_lists=>OptionTextVal[]]]
	 *
	 * @since 1.0.0
	 */
	public function getValidations(bool $formatted = true)
	{
		$ret = [];
		if (is_null($this->validations)) {
			if ($this->element_id > 0) {
				$columns = [
					'validation_type',
					'params',
					'invalid_messages',
				];
				if (!$formatted) {
					$columns = '*';
				}
				$container = Factory::getContainer();
				/** @var DatabaseDriver $db */
				$db    = $container->get('DatabaseDriver');
				$query = $db->getQuery(true);
				$query->select($columns);
				$query->from($db->quoteName('#__formea_element_validations'));
				$query->where($db->quoteName('element_id') . ' = ' . $this->element_id);
				$query->order('id ASC');
				$db->setQuery($query);
				$results = $db->loadObjectList();
				if (!empty($results) && $formatted) {
					$totalResults = count($results);
					for ($i = 0; $i < $totalResults; $i++) {
						$obj    = [];
						$params = [];
						if (!empty($results[$i]->params)) {
							$params = json_decode($results[$i]->params);
						}
						$invalid_msg = [];
						if (!empty($results[$i]->invalid_messages)) {
							$invalid_messages = json_decode($results[$i]->invalid_messages);
							foreach ($invalid_messages as $lang_code => $msg) {
								$langUnderscore               = str_replace('-', '_', $lang_code);
								$invalid_msg[$langUnderscore] = $msg;
							}
						}
						$obj['validation_type'] = $results[$i]->validation_type;
						if (!empty($params)) {
							foreach ($params as $k => $v) {
								$obj[$k] = $v;
							}
						}
						$obj['invalid_msg'] = $invalid_msg;
						$obj['params']      = new Registry($params);
						$ret[]              = $obj;
					}
				} else {
					$ret = $results;
				}
			}
		}

		$this->validations = $ret;

		return $ret;
	}

	public function getElementTypeConfig()
	{
		$ret          = null;
		$elementClass = $this->getElementTypeClass();
		if (!empty($elementClass)) {
			$eltype = $elementClass->getElementType();
			if (isset($eltype->config)) {
				$ret = $eltype->config;
			}
		}
		$this->elementTypeConfig = $ret;

		return $ret;
	}

	/**
	 * Set FormeaElement class property value
	 *
	 * @param $key
	 * @param $value
	 *
	 *
	 * @since 1.0.0
	 */
	public function set($key, $value): void
	{
		if (!empty($key)) {
			$this->{$key} = $value;
		}
	}


	public function getPreview()
	{
		$ret          = [];
		$elementClass = $this->getElementTypeClass();
		if (!empty($elementClass)) {
			$langData      = $this->_getLangData();
			$totalLangData = count($langData);
			for ($i = 0; $i < $totalLangData; $i++) {
				$ret[$langData[$i]] = $elementClass->renderField($this->isPreview, $langData[$i]);
			}
		}
		$this->preview = $ret;

		return $ret;
	}

	public function getPreviewBare()
	{
		$ret = [];
		/** @var FormeaEltype $elementClass */
		$elementClass = $this->getElementTypeClass();
		if (!empty($elementClass)) {
			$langData      = $this->_getLangData();
			$totalLangData = count($langData);
			for ($i = 0; $i < $totalLangData; $i++) {
				$ret[$langData[$i]] = $elementClass->getBareInput($this->isPreview, $langData[$i]);
			}
		}
		$this->previewBare = $ret;

		return $ret;
	}

	public function renderElement($columnAttributes = [], $labelSetting = null)
	{
		$elementClass = $this->getElementTypeClass();
		$ret          = null;
		if (!empty($elementClass)) {
			$inputAttributes = [];
			if (!empty($this->coreClasses)) {
				$cores      = $this->coreClasses;
				$cores      = array_values($cores);
				$totalCores = count($cores);
				for ($i = 0; $i < $totalCores; $i++) {
					$inputAttributes = array_merge($cores[$i]->getInputAttributes($this));
				}
			}

			$ret = $elementClass->renderField(false, $this->langTag, $columnAttributes, $inputAttributes, $labelSetting);
		}

		return $ret;
	}

	public function getElementFormattedName()
	{
		$elementTypeClass = $this->getElementTypeClass();
		$ret              = null;
		if (!empty($elementTypeClass)) {
			$ret = $elementTypeClass->formatElementName();
		}

		return $ret;
	}

	public function renderInputGroup($labelSetting)
	{
		$elementTypeClass = $this->getElementTypeClass();
		$ret              = null;
		if (!empty($elementTypeClass)) {
			$ret = $elementTypeClass->renderInputGroup($this->isPreview, $labelSetting);
		}

		return $ret;
	}

	/**
	 *
	 * @return array
	 *
	 * @since 1.0.0
	 */
	public function getErrorMsg()
	{
		$elementTypeClass = $this->getElementTypeClass();
		$ret              = [];
		if (!empty($elementTypeClass)) {
			$ret = $elementTypeClass->getErrorMsg();
		}

		return $ret;
	}

	/**
	 * @param   FormeaSubmissionElement  $element
	 *
	 * @return mixed
	 *
	 * @since 1.0.5
	 */
	public function beforeValidatingSubmission($element)
	{
		/** @var FormeaEltype $elementClass */
		$elementClass = $this->getElementTypeClass();
		if (!empty($elementClass)) {
			$element = $elementClass->beforeValidatingInput($element);
		}

		return $element;
	}

	public function afterValidatingSubmission($element)
	{
		/** @var FormeaEltype $elementClass */
		$elementClass = $this->getElementTypeClass();
		if (!empty($elementClass)) {
			$element = $elementClass->afterValidatingInput($element);
		}

		return $element;
	}

	public function afterStoringInDb($formObject, $submission_id, $element)
	{
		/** @var FormeaEltype $elementClass */
		$elementClass = $this->getElementTypeClass();
		if (!empty($elementClass)) {
			$element = $elementClass->afterStoringInDb($formObject, $submission_id, $element);
		}

		return $element;
	}

	/**
	 * @param   mixed                    $submitted_value
	 * @param   FormeaSubmissionElement  $element
	 *
	 * @return FsrResponse
	 *
	 * @since 1.0.5
	 */
	public function validateSubmission($submitted_value, $element)
	{
		$retObject = new FsrResponse();
		/** @var FormeaEltype $elementClass */
		$elementClass = $this->getElementTypeClass();
		if (!empty($elementClass)) {
			$validations = $this->getValidations();
			$retObject   = $elementClass->validateInput($submitted_value, $element, $validations);
		}

		return $retObject;
	}

	public function getLabelSettings()
	{
		$ret          = [];
		$elementClass = $this->getElementTypeClass();
		if (!empty($elementClass)) {
			$details     = $this->getDetails(true, true);
			$preview     = $this->getPreview();
			$previewBare = $this->getPreviewBare();
			$ret         = $elementClass->getLabelSettings($details, $preview, $previewBare);
		}
		$this->labelSettings = $ret;

		return $ret;
	}

	public function getElementTypeImage($absoluteUrl = false)
	{
		$elementClass = $this->getElementTypeClass();
		if (empty($this->imageDetails)) {
			if (!empty($elementClass)) {
				$this->imageDetails = (array) $elementClass->getImageDetails($absoluteUrl);
			} else {
				$this->imageDetails = [];
			}
		}

		return $this->imageDetails;
	}

	public function getElementTypeTitle()
	{
		$elementClass = $this->getElementTypeClass();
		if (empty($this->elementTypeTitle)) {
			if (!empty($elementClass)) {
				$this->elementTypeTitle = $elementClass->title;
			} else {
				$this->elementTypeTitle = '';
			}
		}

		return $this->elementTypeTitle;
	}

	public function getElementTypeValueType()
	{
		$elementClass = $this->getElementTypeClass();
		if ($this->value_type < -1) {
			if (!empty($elementClass)) {
				$this->value_type = $elementClass->value_type;
			} else {
				$this->value_type = 0;
			}
		}

		return $this->value_type;
	}

	public function getElementTypeId()
	{
		$elementClass = $this->getElementTypeClass();
		if (empty($this->elementTypeId)) {
			if (!empty($elementClass)) {
				$elementType         = $elementClass->getElementType();
				$this->elementTypeId = $elementClass->id;
			} else {
				$this->elementTypeId = '';
			}
		}

		return $this->elementTypeId;
	}

	public function getElementPreviewSettings()
	{
		$elementClass = $this->getElementTypeClass();
		if (empty($this->previewSettings)) {
			if (!empty($elementClass)) {
				$this->previewSettings = (array) $elementClass->getPreviewSettings();
			} else {
				$this->previewSettings = [];
			}
		}

		return $this->previewSettings;
	}


	/**
	 *
	 * @return FormeaEltype
	 *
	 * @since version
	 */
	public function getElementTypeClass()
	{
		if (empty($this->elementTypeClass)) {
			$element = $this->getElement();
			if (!empty($element)) {
				$fieldName   = $element->alias;
				$elementPath = JPATH_ROOT . '/components/com_formea/plugins/element/' . $element->type . '/';
				$class       = 'Formea' . $element->type;
				if (is_file(Path::clean($elementPath . $class . '.php'))) {
					$details           = $this->getDetails(true, true);
					$values            = $this->getValues(true, true);
					$validationClasses = $this->getValidationClasses();
					require_once $elementPath . $class . '.php';
					$config = [
						'params'            => $element->params,
						'element_id'        => $this->element_id,
						'element_alias'     => $element->alias,
						'name'              => $element->type,
						'element_title'     => $element->title,
						'element_details'   => $details,
						'element_values'    => $values,
						'form_id'           => $this->form_id,
						'isGroup'           => $this->isGroup,
						'group_id'          => $this->group_id,
						'group_type'        => $this->group_type,
						'setIndex'          => $this->setIndex,
						'validationClasses' => $validationClasses
					];
					if (!empty($this->themeClass)) {
						$config['themeClass'] = $this->themeClass;
					}
					if (!empty($this->formUniqueString)) {
						$config['formUniqueString'] = $this->formUniqueString;
					}
					$elementClass           = new $class($config);
					$this->elementTypeClass = $elementClass;
				}
			}
		}

		return $this->elementTypeClass;
	}

	public function setElementTypeClassParam($key, $value)
	{
		$eltypeClass = $this->getElementTypeClass();
		$eltypeClass->set($key, $value);
		$this->elementTypeClass = $eltypeClass;
	}

	public function getAvailableFields()
	{
		$public = (new ReflectionObject($this))->getProperties(ReflectionProperty::IS_PUBLIC);
		$ret    = [];
		if (!empty($public)) {
			$totalPublic = count($public);
			for ($i = 0; $i < $totalPublic; $i++) {
				$ret[] = $public[$i]->getName();
			}
		}

		return $ret;
	}

	/**
	 * Method to delete element
	 * @return FsrResponse
	 *
	 * @since 1.0.0
	 */
	public function deleteElement()
	{
		$retObject = new FsrResponse();
		try {
			if ((int) $this->element_id < 1) {
				throw new Exception(Text::_('COM_FORMEA_NO_ELEMENT_SELECTED'));
			}

			$container = Factory::getContainer();
			/** @var DatabaseDriver $db */
			$db    = $container->get('DatabaseDriver');
			$query = $db->getQuery(true);

			//check if element is in used
			$query->select(['a.title', 'b.form_id']);
			$query->from($db->quoteName('#__formea_elements', 'a'))->innerJoin(
				$db->quoteName('#__formea_form_elements', 'b') . ' ON ' . $db->quoteName('a.id') . ' = ' .
					$db->quoteName('b.element_id')
			);
			$query->where($db->quoteName('a.id') . ' = ' . $db->quote($this->element_id));
			$db->setQuery($query);
			$usedInFormLists = $db->loadObjectList();

			if (!empty($usedInFormLists)) {
				$elementTitle    = '';
				$formLists       = [];
				$totalUsedInForm = count($usedInFormLists);
				for ($i = 0; $i < $totalUsedInForm; $i++) {
					$elementTitle = $usedInFormLists[$i]->title;
				}
				$msg = Text::sprintf('COM_FORMEA_FAILED_TO_DELETE_ELEMENT_IN_USED', $elementTitle);
				throw new Exception($msg);
			}


			$conditions = array(
				$db->quoteName('element_id') . ' = ' . $this->element_id
			);

			$query->clear();
			$query->delete($db->quoteName('#__formea_element_attributes'));
			$query->where($conditions);
			$db->setQuery($query);
			$db->execute();

			$query->clear();
			$query->delete($db->quoteName('#__formea_element_details'));
			$query->where($conditions);
			$db->setQuery($query);
			$db->execute();

			$query->clear();
			$query->delete($db->quoteName('#__formea_element_validations'));
			$query->where($conditions);
			$db->setQuery($query);
			$db->execute();

			$query->clear();
			$query->delete($db->quoteName('#__formea_element_values'));
			$query->where($conditions);
			$db->setQuery($query);
			$db->execute();

			$query->clear();
			$conditions = array(
				$db->quoteName('id') . ' = ' . $this->element_id
			);
			$query->delete($db->quoteName('#__formea_elements'));
			$query->where($conditions);
			$db->setQuery($query);
			$db->execute();

			$retObject->setSuccess(true);
		} catch (Exception $e) {
			$retObject->setSuccess(false);
			$retObject->setMsg($e->getMessage());
		}

		return $retObject;
	}

	protected function _getLangData()
	{
		if (empty($this->langData)) {
			$this->langData = FormeaGeneralHelper::prepareLangData();
		}

		return $this->langData;
	}

	/**
	 * Get the inline JS script to be pushed in the header
	 *
	 * @since 1.0.0
	 */
	public function getGeneratedScript()
	{
		$elementClass = $this->getElementTypeClass();

		return $elementClass->getGeneratedScript();
	}

	/**
	 * Get the inline CSS to be pushed in the header
	 *
	 * @since 1.0.0
	 */
	public function getGeneratedStyle()
	{
		$elementClass = $this->getElementTypeClass();

		return $elementClass->getGeneratedStyle();
	}

	/**
	 * JS file list to load
	 *
	 * @since 1.0.0
	 */
	public function getLoadableScript()
	{
		$elementClass = $this->getElementTypeClass();

		return $elementClass->getLoadableScript();
	}

	/**
	 * CSS file list to load
	 *
	 * @since 1.0.0
	 */
	public function getLoadableStyle()
	{
		$elementClass = $this->getElementTypeClass();

		return $elementClass->getLoadableStyle();
	}
}
