/**
  * Create one DCA field with the specified parameters
  *
  * This function calls itself recursively for nested data structures
  *
  * @param  string         $fieldPrefix    Field prefix, e.g. "rsce_field_"
  * @param  string         $fieldName      Field name
  * @param  array          $fieldConfig    Field configuration array
  * @param  array          $paletteFields  Reference to the list of all fields
  * @param  \DataContainer $dc             Data container
  * @param  boolean        $createFromPost Whether to create the field structure from post data or not
  * @return void
  */
 protected function createDcaItem($fieldPrefix, $fieldName, $fieldConfig, &$paletteFields, $dc, $createFromPost)
 {
     if (!is_string($fieldConfig) && !is_array($fieldConfig)) {
         throw new \Exception('Field config must be of type array or string.');
     }
     if (strpos($fieldName, '__') !== false) {
         throw new \Exception('Field name must not include "__" (' . $this->getDcaFieldValue($dc, 'type') . ': ' . $fieldName . ').');
     }
     if (strpos($fieldName, 'rsce_field_') !== false) {
         throw new \Exception('Field name must not include "rsce_field_" (' . $this->getDcaFieldValue($dc, 'type') . ': ' . $fieldName . ').');
     }
     if (substr($fieldName, 0, 1) === '_' || substr($fieldName, -1) === '_') {
         throw new \Exception('Field name must not start or end with "_" (' . $this->getDcaFieldValue($dc, 'type') . ': ' . $fieldName . ').');
     }
     if (!is_string($fieldName)) {
         $fieldName = 'unnamed_' . $fieldName;
     }
     if (is_string($fieldConfig)) {
         $fieldConfig = array('inputType' => 'group', 'label' => array($fieldConfig, ''));
     }
     if (!\BackendUser::getInstance()->hasAccess($dc->table . '::rsce_data', 'alexf') && $fieldConfig['inputType'] !== 'standardField') {
         return;
     }
     if (isset($fieldConfig['label'])) {
         $fieldConfig['label'] = static::getLabelTranslated($fieldConfig['label']);
     }
     if (isset($fieldConfig['reference']) && is_array($fieldConfig['reference']) && count(array_filter($fieldConfig['reference'], 'is_array'))) {
         $fieldConfig['reference'] = array_map(function ($label) {
             return \MadeYourDay\Contao\CustomElements::getLabelTranslated($label);
         }, $fieldConfig['reference']);
     }
     if ($fieldConfig['inputType'] === 'list') {
         if (isset($fieldConfig['elementLabel'])) {
             $fieldConfig['elementLabel'] = static::getLabelTranslated($fieldConfig['elementLabel']);
         }
         $fieldConfig['minItems'] = isset($fieldConfig['minItems']) ? (int) $fieldConfig['minItems'] : 0;
         $fieldConfig['maxItems'] = isset($fieldConfig['maxItems']) ? (int) $fieldConfig['maxItems'] : null;
         if ($fieldConfig['maxItems'] && $fieldConfig['maxItems'] < $fieldConfig['minItems']) {
             throw new \Exception('maxItems must not be higher than minItems (' . $this->getDcaFieldValue($dc, 'type') . ': ' . $fieldName . ').');
         }
         $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName . '_rsce_list_start'] = array('label' => $fieldConfig['label'], 'inputType' => 'rsce_list_start', 'eval' => array('minItems' => $fieldConfig['minItems'], 'maxItems' => $fieldConfig['maxItems']));
         $paletteFields[] = $fieldPrefix . $fieldName . '_rsce_list_start';
         $hasFields = false;
         foreach ($fieldConfig['fields'] as $fieldConfig2) {
             if (isset($fieldConfig2['inputType']) && $fieldConfig2['inputType'] !== 'list') {
                 $hasFields = true;
             }
         }
         if (!$hasFields) {
             // add an empty field
             $fieldConfig['fields']['rsce_empty'] = array('inputType' => 'text', 'eval' => array('tl_class' => 'hidden'));
         }
         $this->createDcaItemListDummy($fieldPrefix, $fieldName, $fieldConfig, $paletteFields, $dc, $createFromPost);
         $fieldData = $this->getNestedValue($fieldPrefix . $fieldName);
         for ($dataKey = 0; $dataKey < $fieldConfig['minItems'] || ($createFromPost ? $this->wasListFieldSubmitted($fieldPrefix . $fieldName, $dataKey) : isset($fieldData[$dataKey])); $dataKey++) {
             if (is_int($fieldConfig['maxItems']) && $dataKey > $fieldConfig['maxItems'] - 1) {
                 break;
             }
             $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName . '__' . $dataKey . '_rsce_list_item_start'] = array('inputType' => 'rsce_list_item_start', 'label' => array(sprintf($fieldConfig['elementLabel'], $dataKey + 1)), 'eval' => array('label_template' => $fieldConfig['elementLabel']));
             $paletteFields[] = $fieldPrefix . $fieldName . '__' . $dataKey . '_rsce_list_item_start';
             foreach ($fieldConfig['fields'] as $fieldName2 => $fieldConfig2) {
                 $this->createDcaItem($fieldPrefix . $fieldName . '__' . $dataKey . '__', $fieldName2, $fieldConfig2, $paletteFields, $dc, $createFromPost);
             }
             $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName . '__' . $dataKey . '_rsce_list_item_stop'] = array('inputType' => 'rsce_list_item_stop');
             $paletteFields[] = $fieldPrefix . $fieldName . '__' . $dataKey . '_rsce_list_item_stop';
         }
         $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName . '_rsce_list_stop'] = array('inputType' => 'rsce_list_stop');
         $paletteFields[] = $fieldPrefix . $fieldName . '_rsce_list_stop';
     } else {
         if ($fieldConfig['inputType'] === 'standardField') {
             if ($fieldPrefix !== 'rsce_field_') {
                 throw new \Exception('Input type "standardField" is not allowed inside lists.');
             }
             if (isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName])) {
                 if (isset($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName]['eval']) && is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName]['eval']) && isset($fieldConfig['eval']) && is_array($fieldConfig['eval'])) {
                     $fieldConfig['eval'] = array_merge($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName]['eval'], $fieldConfig['eval']);
                 }
                 unset($fieldConfig['inputType']);
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName] = array_merge($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldName], $fieldConfig);
                 $paletteFields[] = $fieldName;
             }
         } else {
             if ($fieldConfig['inputType'] === 'group') {
                 $fieldConfig['inputType'] = 'rsce_group_start';
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName] = $fieldConfig;
                 $paletteFields[] = $fieldPrefix . $fieldName;
             } else {
                 if ($fieldConfig['inputType'] === 'url') {
                     $fieldConfig['inputType'] = 'text';
                     $fieldConfig['wizard'] = array(array('MadeYourDay\\Contao\\CustomElements', 'pagePicker'));
                     $fieldConfig['eval']['tl_class'] = (isset($fieldConfig['eval']['tl_class']) ? $fieldConfig['eval']['tl_class'] . ' ' : '') . 'wizard';
                     if (!isset($fieldConfig['eval']['fieldType'])) {
                         $fieldConfig['eval']['fieldType'] = 'radio';
                     }
                     if (!isset($fieldConfig['eval']['filesOnly'])) {
                         $fieldConfig['eval']['filesOnly'] = true;
                     }
                 }
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName] = $fieldConfig;
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['eval']['alwaysSave'] = true;
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['eval']['doNotSaveEmpty'] = true;
                 if (!is_array($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['load_callback'])) {
                     $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['load_callback'] = array();
                 }
                 array_unshift($GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['load_callback'], array('MadeYourDay\\Contao\\CustomElements', 'loadCallback'));
                 $GLOBALS['TL_DCA'][$dc->table]['fields'][$fieldPrefix . $fieldName]['save_callback'][] = array('MadeYourDay\\Contao\\CustomElements', 'saveCallback');
                 $paletteFields[] = $fieldPrefix . $fieldName;
             }
         }
     }
 }