<?php
/**
 * OrokuBlocks Widget
 * 
 * @package OrokuBlocks
 * @author OrokuBlocks (https://orokublocks.com/)
 * 
 * @since 1.0.0
 * 
 */

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
  exit;
}

class OrokuBlocks_Widget {
  /**
   * Widget id
   * 
   * @since 1.0.0
   * 
   * @access protected
   */
  protected $widget_id;

  /**
   * Default widget options
   * 
   * @since 1.0.0
   * 
   * @access protected
   */
  protected $defaults = [];

  /**
   * Elementor Control sections
   * 
   * @since 1.0.0
   * 
   * @access private
   */
  private $control_sections = [];

  /**
   * Control section modules to load
   * 
   * @since 1.0.0
   * 
   * @access protected
   */
  protected $control_modules = [];

  /**
   * Control section conditions
   * 
   * @since 1.0.0
   * 
   * @access protected
   */
  protected $control_section_conditions = [];

  /**
   * Prevent more than one instance from being created
   * 
   * @since 1.0.0
   * 
   * @access private
   */
  private function __construct() {}

  /**
   * Prevent cloning
   * 
   * @since 1.0.0
   * 
   * @access private
   */
  private function __clone() {}

  /**
   * Returns the class instance
   * 
   * @since 1.0.0
   * 
   * @return OrokuBlocks_Widget $instance  Class instance
   */
  public static function getInstance() {
    static $instances = [];

    $classname = get_called_class();

    if ( ! array_key_exists( $classname, $instances ) ) {
      $instance = new $classname();

      // setup
      $instance->initialize();

      $instance->initializeElementorControlSections();
      $instance->addConditionsToControlSections();
      $instance->addDefaultsToControlSections();
      $instance->addActions();

      $instances[$classname] = $instance;
    }

    return $instances[$classname];
  }

  /**
   * Initialize control sections
   * 
   * @since 1.0.0
   * 
   * @access protected
   */
  protected function initializeElementorControlSections() {
    $versions = [
      'v1'  => [
        'id'    => 'v1',
        'name'  => [
          'free'  => __( 'Version 1', 'orokublocks' ),
          'pro'   => __( 'Version 1 (Pro)', 'orokublocks' )
        ]
      ],
      'v2'  => [
        'id'    => 'v2',
        'name'  => [
          'free'  => __( 'Version 2', 'orokublocks' ),
          'pro'   => __( 'Version 2 (Pro)', 'orokublocks' )
        ]
      ],
      'v3'  => [
        'id'    => 'v3',
        'name'  => [
          'free'  => __( 'Version 3', 'orokublocks' ),
          'pro'   => __( 'Version 3 (Pro)', 'orokublocks' )
        ]
      ],
      'v4'  => [
        'id'    => 'v4',
        'name'  => [
          'free'  => __( 'Version 4', 'orokublocks' ),
          'pro'   => __( 'Version 4 (Pro)', 'orokublocks' )
        ]
      ],
      'v5'  => [
        'id'    => 'v5',
        'name'  => [
          'free'  => __( 'Version 5', 'orokublocks' ),
          'pro'   => __( 'Version 5 (Pro)', 'orokublocks' )
        ]
      ]
    ];

    $version_control_options = [];

    foreach ( orokublocks()->widgets[$this->widget_id]['versions'] as $version_id => $version ) {
      $version_name = $versions[$version_id]['name'];
      $version_control_options[$version_id] = $version['pro'] ? $version_name['pro'] : $version_name['free'];
    }

    $base_control_modules = [
      /**
       * Content
       */
      'content' => [
        'id'    => 'content',
        'args'  => [
          'label'     => __( 'Content', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'title' => [
            'id'    => 'title',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Title', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'title_link' => [
            'id'    => 'title_link',
            'type'  => 'url',
            'args'  => [
              'label'   => __( 'Title Link', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::URL,
              'options' => false
            ]
          ],
          'subtitle' => [
            'id'    => 'subtitle',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Subtitle', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'summary' => [
            'id'    => 'summary',
            'type'  => 'textarea',
            'args'  => [
              'label' => __( 'Summary', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::TEXTAREA
            ]
          ]
        ]
      ],
      'media_content' => [
        'id'    => 'media_content',
        'args'  => [
          'label'     => __( 'Media', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'image_url' => [
            'id'    => 'image_url',
            'type'  => 'media',
            'args'  => [
              'label'   => __( 'Image', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::MEDIA
            ]
          ],
          'embed_url' => [
            'id'    => 'embed_url',
            'type'  => 'url',
            'args'  => [
              'label'       => __('Embed URL', 'orokublocks'),
              'description' => sprintf(
                /* translators: embed URL example. */
                __('Paste your embed URL here, i.e.: %s', 'orokublocks'),
                'https://www.youtube.com/embed/videoID'
              ),
              'type'        => \Elementor\Controls_Manager::URL,
              'options'     => false
            ]
          ]
        ]
      ],
      'user_content' => [
        'id'    => 'user_content',
        'args'  => [
          'label'     => __( 'User', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'avatar_url' => [
            'id'    => 'avatar_url',
            'type'  => 'media',
            'args'  => [
              'label'   => __( 'Avatar', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::MEDIA
            ]
          ],
          'user_text' => [
            'id'    => 'user_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'user_name' => [
            'id'    => 'user_name',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'User Name', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'user_link' => [
            'id'    => 'user_link',
            'type'  => 'url',
            'args'  => [
              'label'   => __( 'User Link', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::URL,
              'options' => false
            ]
          ],
          'verified_user' => [
            'id'    => 'verified_user',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Verified User', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ]
        ]
      ],
      'tags_content' => [
        'id'    => 'tags_content',
        'args'  => [
          'label'     => __( 'Tags', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'tags' => [
            'id'        => 'tags',
            'type'      => 'repeater',
            'controls'  => [
              [
                'id'    => 'text',
                'type'  => 'text',
                'args'  => [
                  'label'   => __( 'Text', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::TEXT,
                  'default' => __( 'TAG TEXT', 'orokublocks' )
                ]
              ],
              [
                'id'    => 'link',
                'type'  => 'url',
                'args'  => [
                  'label'   => __( 'Link', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::URL,
                  'options' => false
                ]
              ],
              [
                'id'    => 'color',
                'type'  => 'color',
                'args'  => [
                  'label' => __( 'Color', 'orokublocks' ),
                  'type'  => \Elementor\Controls_Manager::COLOR
                ]
              ]
            ],
            'args'      => [
              'label'         => __( 'Items', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::REPEATER,
              'prevent_empty' => false
            ]
          ]
        ]
      ],
      'meta_content' => [
        'id'    => 'meta_content',
        'args'  => [
          'label'     => __( 'Meta', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'timestamp' => [
            'id'    => 'timestamp',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Date', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'deal_text' => [
            'id'    => 'deal_text',
            'type'  => 'textarea',
            'args'  => [
              'label' => __( 'Deal Text', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::TEXTAREA
            ]
          ],
          'promo_discount_text' => [
            'id'    => 'promo_discount_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Promo Discount Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'promo_title' => [
            'id'    => 'promo_title',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Promo Title', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'promo_text' => [
            'id'    => 'promo_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Promo Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'score_rating_content' => [
        'id'    => 'score_rating_content',
        'args'  => [
          'label'     => __( 'Score / Rating', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'score_value' => [
            'id'    => 'score_value',
            'type'  => 'number',
            'args'  => [
              'label' => __( 'Score Value', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::NUMBER,
              'min'   => 0,
              'max'   => 100,
              'step'  => .1
            ]
          ],
          'score_max_value' => [
            'id'    => 'score_max_value',
            'type'  => 'number',
            'args'  => [
              'label' => __( 'Score Maximum Value', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::NUMBER,
              'min'   => 0,
              'max'   => 100,
              'step'  => 1
            ]
          ],
          'decimal_points' => [
            'id'    => 'decimal_points',
            'type'  => 'number',
            'args'  => [
              'label' => __( 'Decimal Points', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::NUMBER,
              'min'   => 0,
              'max'   => 1,
              'step'  => 1
            ]
          ],
          'score_separator' => [
            'id'    => 'score_separator',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Score Separator', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'score_text' => [
            'id'    => 'score_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Score Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'details_content' => [
        'id'    => 'details_content',
        'args'  => [
          'label'     => __( 'Details', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'details' => [
            'id'        => 'details',
            'type'      => 'repeater',
            'controls'  => [
              [
                'id'    => 'title',
                'type'  => 'text',
                'args'  => [
                  'label'   => __( 'Title', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::TEXT,
                  'default' => __( 'Detail title', 'orokublocks' )
                ]
              ],
              [
                'id'    => 'text',
                'type'  => 'text',
                'args'  => [
                  'label'   => __( 'Text', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::TEXT,
                  'default' => __( 'Detail text', 'orokublocks' )
                ]
              ],
              [
                'id'    => 'text_link',
                'type'  => 'url',
                'args'  => [
                  'label'   => __( 'Text Link', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::URL,
                  'options' => false
                ]
              ]
            ],
            'args'      => [
              'label'         => __( 'Detail Items', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::REPEATER,
              'prevent_empty' => false
            ]
          ]
        ]
      ],
      'recommendation_content'  => [
        'id'    => 'recommendation_content',
        'args'  => [
          'label'     => __( 'Recommendation', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'recommendation_title' => [
            'id'    => 'recommendation_title',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Title', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'recommendation_text' => [
            'id'    => 'recommendation_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'recommendation_image_url' => [
            'id'    => 'recommendation_image_url',
            'type'  => 'media',
            'args'  => [
              'label'   => __( 'Image', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::MEDIA
            ]
          ]
        ]
      ],
      'pros_cons_content' => [
        'id'    => 'pros_cons_content',
        'args'  => [
          'label'     => __( 'Pros / Cons', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'pros_title' => [
            'id'    => 'pros_title',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Pros Title', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'pros' => [
            'id'        => 'pros',
            'type'      => 'repeater',
            'controls'  => [
              [
                'id'    => 'text',
                'type'  => 'text',
                'args'  => [
                  'label'   => __( 'Text', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::TEXT,
                  'default' => __( 'Something good', 'orokublocks' )
                ]
              ]
            ],
            'args'      => [
              'label'         => __( 'Pros', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::REPEATER,
              'prevent_empty' => false
            ]
          ],
          'cons_title' => [
            'id'    => 'cons_title',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Cons Title', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'cons' => [
            'id'        => 'cons',
            'type'      => 'repeater',
            'controls'  => [
              [
                'id'    => 'text',
                'type'  => 'text',
                'args'  => [
                  'label'   => __( 'Text', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::TEXT,
                  'default' => __( 'Something bad', 'orokublocks' )
                ]
              ]
            ],
            'args'      => [
              'label'         => __( 'Cons', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::REPEATER,
              'prevent_empty' => false
            ]
          ]
        ]
      ],
      'progress_bars_content' => [
        'id'    => 'progress_bars_content',
        'args'  => [
          'label'     => __( 'Progress Bars', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'progress_bars' => [
            'id'        => 'progress_bars',
            'type'      => 'repeater',
            'controls'  => [
              [
                'id'    => 'text',
                'type'  => 'text',
                'args'  => [
                  'label'   => __( 'Text', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::TEXT,
                  'default' => __( 'ITEM TEXT', 'orokublocks' )
                ]
              ],
              [
                'id'    => 'value',
                'type'  => 'number',
                'args'  => [
                  'label'   => __( 'Value', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::NUMBER,
                  'min'     => 0,
                  'max'     => 100,
                  'step'    => .1,
                  'default' => 5
                ]
              ],
              [
                'id'    => 'max_value',
                'type'  => 'number',
                'args'  => [
                  'label'   => __( 'Maximum Value', 'orokublocks' ),
                  'type'    => \Elementor\Controls_Manager::NUMBER,
                  'min'     => 0,
                  'max'     => 100,
                  'step'    => 1,
                  'default' => 10
                ]
              ]
            ],
            'args'      => [
              'label'         => __( 'Items', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::REPEATER,
              'prevent_empty' => false
            ]
          ]
        ]
      ],
      'countdown_content' => [
        'id'    => 'countdown_content',
        'args'  => [
          'label'     => __( 'Countdown', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'countdown_enabled' => [
            'id'    => 'countdown_enabled',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Enable Countdown', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ],
          'countdown_target_date' => [
            'id'    => 'countdown_target_date',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Target Date', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::DATE_TIME
            ]
          ],
          'countdown_expiration_text' => [
            'id'    => 'countdown_expiration_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Expiration Text', 'orokublocks' ),
              'description' => __( 'Text to display when the countdown finishes', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'countdown_days_text' => [
            'id'    => 'countdown_days_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Days Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'countdown_hours_text' => [
            'id'    => 'countdown_hours_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Hours Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'countdown_minutes_text' => [
            'id'    => 'countdown_minutes_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Minutes Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'countdown_seconds_text' => [
            'id'    => 'countdown_seconds_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Seconds Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'button_content'  => [
        'id'    => 'button_content',
        'args'  => [
          'label'     => __( 'Button', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'button_text' => [
            'id'    => 'button_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Button Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'button_link' => [
            'id'    => 'button_link',
            'type'  => 'url',
            'args'  => [
              'label'   => __( 'Button Link', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::URL,
              'options' => false
            ]
          ]
        ]
      ],
      'buttons_content'  => [
        'id'    => 'buttons_content',
        'args'  => [
          'label'     => __( 'Buttons', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'button1_text' => [
            'id'    => 'button1_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Button Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'button1_link' => [
            'id'    => 'button1_link',
            'type'  => 'url',
            'args'  => [
              'label'   => __( 'Button Link', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::URL,
              'options' => false
            ]
          ],
          'button2_text' => [
            'id'    => 'button2_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Button Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'button2_link' => [
            'id'    => 'button2_link',
            'type'  => 'url',
            'args'  => [
              'label'   => __( 'Button Link', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::URL,
              'options' => false
            ]
          ]
        ]
      ],
      'share_actions' => [
        'id'    => 'share_actions',
        'args'  => [
          'label'     => __( 'Share / Actions', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'footer_left_title' => [
            'id'    => 'footer_left_title',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Footer Title', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'share_facebook_enabled' => [
            'id'    => 'share_facebook_enabled',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Facebook Share', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ],
          'share_x_enabled' => [
            'id'    => 'share_x_enabled',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'X Share', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ]
        ]
      ],
      /**
       * GamiPress
       */
      'gamipress_achievement_content' => [
        'id'    => 'gamipress_achievement_content',
        'args'  => [
          'label'     => __( 'Achievement', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'achievement_name' => [
            'id'    => 'achievement_name',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Name', 'orokublocks' ),
              'description' => sprintf(
                /* translators: 1: opening strong tag, 2: closing strong tag, 3: break line tag, 4: opening strong tag, 5: closing strong tag, 6: opening strong tag, 7: closing strong tag. */
                __( 'Enter the %1$sslug%2$s of the achievement that you want to display.%3$sTo find the achievement slug, from your WordPress backend, go to %4$sAchievements%5$s and open the achievement you want to find the slug of. Once open, consult the %6$sSlug%7$s row in the right hand side panel.', 'orokublocks' ),
                '<strong>',
                '</strong>',
                '<br><br>',
                '<strong>',
                '</strong>',
                '<strong>',
                '</strong>'
              ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'gamipress_rank_content' => [
        'id'    => 'gamipress_rank_content',
        'args'  => [
          'label'     => __( 'Rank', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'rank_name' => [
            'id'    => 'rank_name',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Name', 'orokublocks' ),
              'description' => sprintf(
                /* translators: 1: opening strong tag, 2: closing strong tag, 3: break line tag, 4: opening strong tag, 5: closing strong tag, 6: opening strong tag, 7: closing strong tag. */
                __( 'Enter the %1$sslug%2$s of the rank that you want to display.%3$sTo find the rank slug, from your WordPress backend, go to %4$sRanks%5$s and open the rank you want to find the slug of. Once open, consult the %6$sSlug%7$s row in the right hand side panel.', 'orokublocks' ),
                '<strong>',
                '</strong>',
                '<br><br>',
                '<strong>',
                '</strong>',
                '<strong>',
                '</strong>'
              ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'gamipress_point_content' => [
        'id'    => 'gamipress_point_content',
        'args'  => [
          'label'     => __( 'Point', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'point_name' => [
            'id'    => 'point_name',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Name', 'orokublocks' ),
              'description' => sprintf(
                /* translators: 1: opening strong tag, 2: closing strong tag, 3: break line tag, 4: opening strong tag, 5: closing strong tag, 6: opening strong tag, 7: closing strong tag. */
                __( 'Enter the %1$sslug%2$s of the point type that you want to display.%3$sTo find the point type slug, from your WordPress backend, go to %4$sGamiPress%5$s > %6$sPoints Types%7$s. You can find the slug either directly from the list or by opening the point type you want to find the slug of.', 'orokublocks' ),
                '<strong>',
                '</strong>',
                '<br><br>',
                '<strong>',
                '</strong>',
                '<strong>',
                '</strong>'
              ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'gamipress_media_content' => [
        'id'    => 'gamipress_media_content',
        'args'  => [
          'label'     => __( 'Media', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'cover_image_url' => [
            'id'    => 'cover_image_url',
            'type'  => 'media',
            'args'  => [
              'label'   => __( 'Cover Image', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::MEDIA
            ]
          ]
        ]
      ],
      'gamipress_content'  => [
        'id'    => 'gamipress_content',
        'args'  => [
          'label'     => __( 'Content', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'progress_text' => [
            'id'    => 'progress_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Progress Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'locked_text' => [
            'id'    => 'locked_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Locked Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'unlocked_text' => [
            'id'    => 'unlocked_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Unlocked Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'gamipress_steps_content'  => [
        'id'    => 'gamipress_steps_content',
        'args'  => [
          'label'     => __( 'Steps', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'steps_title' => [
            'id'    => 'steps_title',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Steps Title', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'gamipress_earners_content' => [
        'id'    => 'gamipress_earners_content',
        'args'  => [
          'label'     => __( 'Earners', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'earners_text' => [
            'id'    => 'earners_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'gamipress_point_text_content' => [
        'id'    => 'gamipress_point_text_content',
        'args'  => [
          'label'     => __( 'Content', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'summary' => [
            'id'    => 'summary',
            'type'  => 'textarea',
            'args'  => [
              'label' => __( 'Summary', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::TEXTAREA
            ]
          ]
        ]
      ],
      'gamipress_point_modifiers_content' => [
        'id'    => 'gamipress_point_modifiers_content',
        'args'  => [
          'label'     => __( 'Awards / Deducts', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'tasks_text' => [
            'id'    => 'tasks_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Tasks Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'awards_text' => [
            'id'    => 'awards_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Awards Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'deducts_text' => [
            'id'    => 'deducts_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Deducts Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'limit_text' => [
            'id'    => 'limit_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Limit Text', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'limit_unlimited_text' => [
            'id'    => 'limit_unlimited_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Limit Text - Unlimited', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'limit_minutely_text' => [
            'id'    => 'limit_minutely_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Limit Text - Minutely', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'limit_hourly_text' => [
            'id'    => 'limit_hourly_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Limit Text - Hourly', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'limit_daily_text' => [
            'id'    => 'limit_daily_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Limit Text - Daily', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'limit_weekly_text' => [
            'id'    => 'limit_weekly_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Limit Text - Weekly', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'limit_monthly_text' => [
            'id'    => 'limit_monthly_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Limit Text - Monthly', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'limit_yearly_text' => [
            'id'    => 'limit_yearly_text',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Limit Text - Yearly', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      /**
       * SportsPress
       */
      'sportspress_player_content' => [
        'id'    => 'sportspress_player_content',
        'args'  => [
          'label'     => __( 'Player', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'player_id' => [
            'id'    => 'player_id',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'ID', 'orokublocks' ),
              'description' => sprintf(
                /* translators: 1: opening strong tag, 2: closing strong tag, 3: break line tag, 4: opening strong tag, 5: closing strong tag, 6: opening strong tag, 7: closing strong tag. */
                __( 'Enter the %1$sid%2$s of the player that you want to display.%3$sTo find the player id, from your WordPress backend, go to %4$sPlayers%5$s and open the player you want to find the id of. Once open, consult the %6$sShortcodes%7$s section in the right hand side panel, the number that displays inside the shortcodes is the player id.', 'orokublocks' ),
                '<strong>',
                '</strong>',
                '<br><br>',
                '<strong>',
                '</strong>',
                '<strong>',
                '</strong>'
              ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'sportspress_media_content' => [
        'id'    => 'sportspress_media_content',
        'args'  => [
          'label'     => __( 'Media', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'cover_image_url' => [
            'id'    => 'cover_image_url',
            'type'  => 'media',
            'args'  => [
              'label'   => __( 'Cover Image', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::MEDIA
            ]
          ]
        ]
      ],
      'sportspress_player_metrics'  => [
        'id'    => 'sportspress_player_metrics',
        'args'  => [
          'label'     => __( 'Metrics', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'sportspress_metrics' => [
            'id'        => 'sportspress_metrics',
            'type'      => 'repeater',
            'controls'  => [
              [
                'id'    => 'metric',
                'type'  => 'sportspress_metrics',
                'args'  => [
                  'label' => __( 'Metric', 'orokublocks' ),
                  'type'  => \Elementor\Controls_Manager::SELECT
                ]
              ]
            ],
            'args'      => [
              'label'         => __( 'Metric', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::REPEATER,
              'prevent_empty' => false
            ]
          ]
        ]
      ],
      'sportspress_event_content' => [
        'id'    => 'sportspress_event_content',
        'args'  => [
          'label'     => __( 'Event', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'event_id' => [
            'id'    => 'event_id',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'ID', 'orokublocks' ),
              'description' => sprintf(
                /* translators: 1: opening strong tag, 2: closing strong tag, 3: break line tag, 4: opening strong tag, 5: closing strong tag, 6: opening strong tag, 7: closing strong tag. */
                __( 'Enter the %1$sid%2$s of the event that you want to display.%3$sTo find the event id, from your WordPress backend, go to %4$sEvents%5$s and open the event you want to find the id of. Once open, consult the %6$sShortcodes%7$s section in the right hand side panel, the number that displays inside the shortcodes is the event id.', 'orokublocks' ),
                '<strong>',
                '</strong>',
                '<br><br>',
                '<strong>',
                '</strong>',
                '<strong>',
                '</strong>'
              ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ],
          'link_to_event' => [
            'id'    => 'link_to_event',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Link to Event', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ]
        ]
      ],
      /**
       * WooCommerce
       */
      'woocommerce_product_content' => [
        'id'    => 'woocommerce_product_content',
        'args'  => [
          'label'     => __( 'Product', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'product_id' => [
            'id'    => 'product_id',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'ID', 'orokublocks' ),
              'description' => sprintf(
                /* translators: 1: opening strong tag, 2: closing strong tag, 3: break line tag, 4: opening strong tag, 5: closing strong tag. */
                __( 'Enter the %1$sid%2$s of the product that you want to display.%3$sTo find the product id, from your WordPress backend, go to %4$sProducts%5$s. You can find the id by positioning your mouse over the product in the list.', 'orokublocks' ),
                '<strong>',
                '</strong>',
                '<br><br>',
                '<strong>',
                '</strong>'
              ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      'woocommerce_product_attributes' => [
        'id'    => 'woocommerce_product_attributes',
        'args'  => [
          'label'     => __( 'Attributes', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls' => [
          'attributes_display' => [
            'id'    => 'attributes_display',
            'type'  => 'text',
            'args'  => [
              'label'       => __( 'Attributes', 'orokublocks' ),
              'description' => __( 'Enter the id of the attributes that you want to display for this product separated by a comma (e.g. "size, weight").', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::TEXT,
              'input_type'  => 'text'
            ]
          ]
        ]
      ],
      /**
       * Style
       */
      'theme' => [
        'id'    => 'theme',
        'args'  => [
          'label'     => __( 'Theme', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'theme' => [
            'id'    => 'theme',
            'type'  => 'select',
            'args'  => [
              'label'   => __( 'Theme', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::SELECT,
              'options' => [
                'light' => __( 'Light', 'orokublocks' ),
                'dark'  => __( 'Dark', 'orokublocks' )
              ]
            ]
          ]
        ]
      ],
      'theme_light' => [
        'id'    => 'theme_light',
        'args'  => [
          'label'     => __( 'Theme - Light', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'light_primary_color' => [
            'id'    => 'light_primary_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Primary Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'light_background_color' => [
            'id'    => 'light_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'light_background_alt_color' => [
            'id'    => 'light_background_alt_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Background Alt Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'light_line_color' => [
            'id'    => 'light_line_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Line Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'light_text_color' => [
            'id'    => 'light_text_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Text Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'theme_dark'  => [
        'id'    => 'theme_dark',
        'args'  => [
          'label'     => __( 'Theme - Dark', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'dark_primary_color' => [
            'id'    => 'dark_primary_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Primary Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'dark_background_color' => [
            'id'    => 'dark_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'dark_background_alt_color' => [
            'id'    => 'dark_background_alt_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Background Alt Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'dark_line_color' => [
            'id'    => 'dark_line_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Line Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'dark_text_color' => [
            'id'    => 'dark_text_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Text Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'font'  => [
        'id'    => 'font',
        'args'  => [
          'label'     => __( 'Font', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'use_plugin_font' => [
            'id'    => 'use_plugin_font',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Use plugin font', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes',
            ]
          ],
          'font_scale' => [
            'id'    => 'font_scale',
            'type'  => 'number',
            'args'  => [
              'label' => __( 'Font Scale', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::NUMBER,
              'min'   => 1,
              'max'   => 1.5,
              'step'  => .01
            ]
          ]
        ]
      ],
      'card'  => [
        'id'    => 'card',
        'args'  => [
          'label'     => __( 'Card', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'width' => [
            'id'    => 'width',
            'type'  => 'number',
            'args'  => [
              'label'       => __( 'Width', 'orokublocks' ),
              'description' => __( 'Use a value of 0 to let the card auto adjust size.', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::NUMBER,
              'min'         => 0,
              'step'        => 1
            ]
          ],
          'card_border_radius' => [
            'id'    => 'card_border_radius',
            'type'  => 'number',
            'args'  => [
              'label' => __( 'Border Radius', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::NUMBER,
              'min'   => 0,
              'step'  => 1
            ]
          ]
        ]
      ],
      'media_style' => [
        'id'    => 'media_style',
        'args'  => [
          'label'     => __( 'Media', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'card_image_border_radius' => [
            'id'    => 'card_image_border_radius',
            'type'  => 'number',
            'args'  => [
              'label' => __( 'Image Border Radius', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::NUMBER,
              'min'   => 0,
              'step'  => 1
            ]
          ]
        ]
      ],
      'user_style'  => [
        'id'    => 'user_style',
        'args'  => [
          'label'     => __( 'User', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'user_avatar_border_color' => [
            'id'    => 'user_avatar_border_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Avatar Border Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'user_avatar_gradient' => [
            'id'    => 'user_avatar_gradient',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Use Gradient Colors', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ],
          'user_avatar_gradient_start_color' => [
            'id'    => 'user_avatar_gradient_start_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Avatar Gradient Start Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'user_avatar_gradient_end_color' => [
            'id'    => 'user_avatar_gradient_end_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Avatar Gradient End Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'verified_user_color' => [
            'id'    => 'verified_user_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Verified User Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'rating_style'  => [
        'id'    => 'rating_style',
        'args'  => [
          'label'     => __( 'Rating', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'rating_color' => [
            'id'    => 'rating_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Rating Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'rating_underline_color' => [
            'id'    => 'rating_underline_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Rating Underline Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'meta_style'  => [
        'id'    => 'meta_style',
        'args'  => [
          'label'     => __( 'Meta', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls'  => [
          'promo_discount_text_gradient_color' => [
            'id'    => 'promo_discount_text_gradient_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Promo Discount Text Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'promo_discount_text_gradient' => [
            'id'    => 'promo_discount_text_gradient',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Use Gradient Colors', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ],
          'promo_discount_text_gradient_start_color' => [
            'id'    => 'promo_discount_text_gradient_start_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Promo Discount Text Gradient Start Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'promo_discount_text_gradient_end_color' => [
            'id'    => 'promo_discount_text_gradient_end_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Promo Discount Text Gradient End Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'progress_bars_style'  => [
        'id'    => 'progress_bars_style',
        'args'  => [
          'label'     => __( 'Progress Bar', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'animate_on_scroll' => [
            'id'    => 'animate_on_scroll',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Animate Progress On Scroll', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ],
          'progress_bar_width' => [
            'id'    => 'progress_bar_width',
            'type'  => 'number',
            'args'  => [
              'label'       => __('Progress bar width', 'orokublocks'),
              'type'        => \Elementor\Controls_Manager::NUMBER,
              'min'         => 200,
              'step'        => 10
            ]
          ],
          'progress_bar_breakpoint_width' => [
            'id'    => 'progress_bar_breakpoint_width',
            'type'  => 'number',
            'args'  => [
              'label'       => __('Progress bar breakpoint width', 'orokublocks'),
              'description' => __('Screen width that is used to change the progress bar size for mobile.', 'orokublocks'),
              'type'        => \Elementor\Controls_Manager::NUMBER,
              'min'         => 0,
              'step'        => 10
            ]
          ],
          'progress_bar_split_parts' => [
            'id'    => 'progress_bar_split_parts',
            'type'  => 'number',
            'args'  => [
              'label'       => __('Progress bar split parts', 'orokublocks'),
              'description' => __('The number of parts in which to divide the progress bar.', 'orokublocks'),
              'type'        => \Elementor\Controls_Manager::NUMBER,
              'min'         => 1,
              'step'        => 1
            ]
          ],
          'progress_bar_color' => [
            'id'    => 'progress_bar_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Progress Bar Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'progress_bar_underline_color' => [
            'id'    => 'progress_bar_underline_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Progress Bar Underline Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'progress_bar_gradient' => [
            'id'    => 'progress_bar_gradient',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Use Gradient Colors', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ],
          'progress_bar_gradient_start_color' => [
            'id'    => 'progress_bar_gradient_start_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Progress Bar Gradient Start Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'progress_bar_gradient_end_color' => [
            'id'    => 'progress_bar_gradient_end_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Progress Bar Gradient End Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'pros_cons_style' => [
        'id'    => 'pros_cons_style',
        'args'  => [
          'label'     => __( 'Pros / Cons', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'pros_icon' => [
            'id'    => 'pros_icon',
            'type'  => 'select',
            'args'  => [
              'label'       => __( 'Pros Icon', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::SELECT,
              'options'     => [
                ''          => __( 'Default', 'orokublocks' ),
                'lightning' => __( 'Lightning', 'orokublocks' )
              ]
            ]
          ],
          'pros_status_tag_style' => [
            'id'    => 'pros_status_tag_style',
            'type'  => 'select',
            'args'  => [
              'label'       => __( 'Pros Icon Style', 'orokublocks' ),
              'description' => __( 'If you change the style between background and outline / regular types, the icons may seem to disappear, but its because the icons are the same color as the background. You can edit background and icon colors from the options below.', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::SELECT,
              'options'     => [
                'regular'           => __( 'Regular', 'orokublocks' ),
                'background'        => __( 'Background', 'orokublocks' ),
                'background-round'  => __( 'Background Round', 'orokublocks' ),
                'outline'           => __( 'Outline', 'orokublocks' )
              ]
            ]
          ],
          'status_tag_enabled_icon_color' => [
            'id'    => 'status_tag_enabled_icon_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Pros Icon Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'status_tag_enabled_background_color' => [
            'id'    => 'status_tag_enabled_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Pros Icon Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'cons_icon' => [
            'id'    => 'cons_icon',
            'type'  => 'select',
            'args'  => [
              'label'       => __( 'Cons Icon', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::SELECT,
              'options'     => [
                ''          => __( 'Default', 'orokublocks' ),
                'lightning' => __( 'Lightning', 'orokublocks' )
              ]
            ]
          ],
          'cons_status_tag_style' => [
            'id'    => 'cons_status_tag_style',
            'type'  => 'select',
            'args'  => [
              'label'       => __( 'Cons Icon Style', 'orokublocks' ),
              'description' => __( 'If you change the style between background and outline / regular types, the icons may seem to disappear, but its because the icons are the same color as the background. You can edit background and icon colors from the options below.', 'orokublocks' ),
              'type'        => \Elementor\Controls_Manager::SELECT,
              'options'     => [
                'regular'           => __( 'Regular', 'orokublocks' ),
                'background'        => __( 'Background', 'orokublocks' ),
                'background-round'  => __( 'Background Round', 'orokublocks' ),
                'outline'           => __( 'Outline', 'orokublocks' )
              ]
            ]
          ],
          'status_tag_disabled_icon_color' => [
            'id'    => 'status_tag_disabled_icon_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Cons Icon Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'status_tag_disabled_background_color' => [
            'id'    => 'status_tag_disabled_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Cons Icon Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      /**
       * GamiPress
       */
      'gamipress_content_style'  => [
        'id'    => 'gamipress_content_style',
        'args'  => [
          'label'     => __( 'Content', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls'  => [
          'achievement_unlocked_background_color' => [
            'id'    => 'achievement_unlocked_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Achievement Unlocked Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'achievement_unlocked_background_gradient' => [
            'id'    => 'achievement_unlocked_background_gradient',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Use Gradient Colors', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ],
          'achievement_unlocked_background_gradient_start_color' => [
            'id'    => 'achievement_unlocked_background_gradient_start_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Achievement Unlocked Background Gradient Start Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'achievement_unlocked_background_gradient_end_color' => [
            'id'    => 'achievement_unlocked_background_gradient_end_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Achievement Unlocked Background Gradient End Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'gamipress_point_amount_style'  => [
        'id'    => 'gamipress_point_amount_style',
        'args'  => [
          'label'     => __( 'Point Amount', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls'  => [
          'point_amount_text_gradient_color' => [
            'id'    => 'point_amount_text_gradient_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Text Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'point_amount_text_gradient' => [
            'id'    => 'point_amount_text_gradient',
            'type'  => 'switcher',
            'args'  => [
              'label'         => __( 'Use Gradient Colors', 'orokublocks' ),
              'type'          => \Elementor\Controls_Manager::SWITCHER,
              'return_value'  => 'yes'
            ]
          ],
          'point_amount_text_gradient_start_color' => [
            'id'    => 'point_amount_text_gradient_start_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Text Gradient Start Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'point_amount_text_gradient_end_color' => [
            'id'    => 'point_amount_text_gradient_end_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Text Gradient End Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'gamipress_point_modifiers_style' => [
        'id'    => 'gamipress_point_modifiers_style',
        'args'  => [
          'label'     => __( 'Awards / Deducts', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'awards_tag_icon_color' => [
            'id'    => 'awards_tag_icon_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Awards Icon Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'awards_tag_background_color' => [
            'id'    => 'awards_tag_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Awards Icon Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'deducts_tag_icon_color' => [
            'id'    => 'deducts_tag_icon_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Deducts Icon Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'deducts_tag_background_color' => [
            'id'    => 'deducts_tag_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Deducts Icon Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      /**
       * SportsPress
       */
      'sportspress_player_style' => [
        'id'    => 'sportspress_player_style',
        'args'  => [
          'label'     => __( 'Player', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'player_image_style' => [
            'id'    => 'player_image_style',
            'type'  => 'select',
            'args'  => [
              'label'   => __( 'Player Image Style', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::SELECT,
              'options' => [
                'contained' => __( 'Contained', 'orokublocks' ),
                'overflow'  => __( 'Overflow', 'orokublocks' )
              ]
            ]
          ],
          'player_background_type' => [
            'id'    => 'player_background_type',
            'type'  => 'select',
            'args'  => [
              'label'   => __( 'Player Background Type', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::SELECT,
              'options' => [
                'color'     => __( 'Color', 'orokublocks' ),
                'gradient'  => __( 'Gradient', 'orokublocks' ),
                'image'     => __( 'Image', 'orokublocks' )
              ]
            ]
          ],
          'player_background_color' => [
            'id'    => 'player_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Player Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR,
              'condition' => [
                'player_background_type'  => 'color'
              ]
            ]
          ],
          'player_background_gradient_start_color' => [
            'id'    => 'player_background_gradient_start_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Player Background Gradient Start Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR,
              'condition' => [
                'player_background_type'  => 'gradient'
              ]
            ]
          ],
          'player_background_gradient_end_color' => [
            'id'    => 'player_background_gradient_end_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Player Background Gradient End Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR,
              'condition' => [
                'player_background_type'  => 'gradient'
              ]
            ]
          ],
          'player_overlay_color' => [
            'id'    => 'player_overlay_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Player Overlay Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'player_tag_color' => [
            'id'    => 'player_tag_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Player Tag Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ],
          'player_metrics_background_color' => [
            'id'    => 'player_metrics_background_color',
            'type'  => 'color',
            'args'  => [
              'label' => __( 'Player Metrics Background Color', 'orokublocks' ),
              'type'  => \Elementor\Controls_Manager::COLOR
            ]
          ]
        ]
      ],
      'sportspress_frame_style' => [
        'id'    => 'sportspress_frame_style',
        'args'  => [
          'label'     => __( 'Frame', 'orokublocks' ),
          'tab'       => \Elementor\Controls_Manager::TAB_STYLE
        ],
        'controls' => [
          'frame_style' => [
            'id'    => 'frame_style',
            'type'  => 'select',
            'args'  => [
              'label'   => __( 'Frame Style', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::SELECT,
              'options' => [
                'holographic'         => __( 'Holographic', 'orokublocks' ),
                'holographic--gold'   => __( 'Holographic Gold', 'orokublocks' ),
                'holographic--silver' => __( 'Holographic Silver', 'orokublocks' )
              ]
            ]
          ]
        ]
      ]
    ];

    $this->control_sections = [
      'version' => [
        'id'    => 'version',
        'args'  => [
          'label' => __( 'Version', 'orokublocks' ),
          'tab'   => \Elementor\Controls_Manager::TAB_CONTENT
        ],
        'controls'  => [
          'version' => [
            'id'    => 'version',
            'type'  => 'select',
            'args'  => [
              'label'   => __( 'Version', 'orokublocks' ),
              'type'    => \Elementor\Controls_Manager::SELECT,
              'default' => 'v1',
              'options' => $version_control_options
            ]
          ]
        ]
      ]
    ];

    foreach ( $this->control_modules as $control_section_id => $control_ids ) {
      if ( array_key_exists( $control_section_id, $base_control_modules ) ) {
        $control_section = $base_control_modules[$control_section_id];

        // if provided, load only specified controls for this section
        if ( count( $control_ids ) > 0 ) {
          $control_section['controls'] = array_filter(
            $control_section['controls'],
            function ( $control_id ) use ( $control_ids ) {
              return in_array( $control_id, $control_ids );
            },
            ARRAY_FILTER_USE_KEY
          );
        }

        $this->control_sections[$control_section_id] = $control_section;
      }
    }
  }

  /**
   * Add default values to control sections
   * 
   * @since 1.0.0
   */
  private function addDefaultsToControlSections() {
    // assign default values if provided
    foreach ( $this->control_sections as $control_section_id => $control_section ) {
      foreach ( $control_section['controls'] as $control_id => $control ) {
        // default value exists for this control
        if ( array_key_exists( $control_id, $this->defaults ) ) {
          if ( in_array( $control['type'], [ 'url', 'media' ] ) ) {
            $default_value = [
              'url' => $this->defaults[$control_id]
            ];
          } else if ( $control['type'] === 'switcher' ) {
            $default_value = $this->defaults[$control_id] ? 'yes' : 'no';
          } else {
            $default_value = $this->defaults[$control_id];
          }

          $this->control_sections[$control_section_id]['controls'][$control_id]['args']['default'] = $default_value;
        }
      }
    }
  }

  /**
   * Add conditions to control sections
   * 
   * @since 1.0.0
   */
  private function addConditionsToControlSections() {
    $widget_pro_versions = orokublocks()->getWidgetProVersions( $this->widget_id );
    $widget_free_versions = orokublocks()->getWidgetFreeVersions( $this->widget_id );
    
    if ( ! orokublocks()->isProVersionValid() ) {
      $this->control_sections['version']['controls']['version_pro_notice'] = [
        'id'      => 'version_pro_notice',
        'type'    => 'raw_html',
        'args'    => [
          'type'            => \Elementor\Controls_Manager::RAW_HTML,
          'raw'             => sprintf(
            /* translators: 1: opening anchor tag, 2: closing anchor tag. */
            __( 'Upgrade to %1$sPro version%2$s to get access to this widget and much more!. ', 'orokublocks' ),
            '<a href="' . esc_url( orokublocks()->getUnlockProUrl() ) . '" target="_blank">',
            '</a>'
          ),
          'content_classes' => 'orokublocks-upgrade-notice',
          'condition'       => [
            'version' => $widget_pro_versions
          ]
        ]
      ];
    }

    // if there are free versions, add conditions for them
    if ( count( $widget_pro_versions ) !== 0 ) {
      // assign conditions to control sections other than version
      foreach ( $this->control_sections as $control_section_id => $control_section ) {
        if ( ! orokublocks()->isProVersionValid() && ( $control_section_id !== 'version' ) ) {
          $this->control_sections[$control_section_id]['args']['condition'] = [
            'version' => $widget_free_versions
          ];
        }
      }
    }

    // assign conditions to control sections
    foreach ( $this->control_section_conditions as $control_section_id => $control_section ) {
      if ( array_key_exists( 'condition', $control_section ) ) {
        if ( array_key_exists( 'version', $control_section['condition'] ) ) {
          // filter out pro versions accordingly
          $control_section['condition']['version'] = array_filter(
            $control_section['condition']['version'],
            function ( $version ) use ( $widget_free_versions ) {
              return orokublocks()->isProVersionValid() || in_array( $version, $widget_free_versions );
            }
          );
        }
        
        $this->setElementorControlSectionCondition( $control_section_id , $control_section['condition'] );
      }
      
      if ( array_key_exists( 'controls', $control_section ) ) {
        $controls = $control_section['controls'];

        foreach ( $control_section['controls'] as $control_id => $control_condition ) {
          $this->setElementorControlCondition( $control_section_id, $control_id, $control_condition );
        }
      }
    }
  }

  /**
   * Add control sections
   * 
   * @since 1.0.0
   * 
   * @param array $control_sections         Control sections to add.
   * 
   * @access protected
   */
  protected function addElementorControlSections( $control_sections ) {
    $this->control_sections = array_merge( $this->control_sections, $control_sections );
  }

  /**
   * Add controls to a section
   * 
   * @since 1.0.0
   * 
   * @param string $control_section_id        Id of the section to add controls to.
   * @param array  $controls                  Elementor controls.
   */
  protected function addElementorControls( $control_section_id, $controls ) {
    if ( array_key_exists( $control_section_id, $this->control_sections ) ) {
      $this->control_sections[$control_section_id]['controls'] = array_merge( $this->control_sections[$control_section_id]['controls'], $controls );
    }
  }

  /**
   * Set a condition for rendering a control section
   * 
   * @since 1.0.0
   * 
   * @param string $control_section_id        Id of the section to set a condition to.
   * @param array  $condition                 Render condition.
   */
  private function setElementorControlSectionCondition( $control_section_id, $condition ) {
    if ( array_key_exists( $control_section_id, $this->control_sections ) ) {
      $this->control_sections[$control_section_id]['args']['condition'] = $condition;
    }
  }

  /**
   * Set a condition for rendering the control of a section
   * 
   * @since 1.0.0
   * 
   * @param string $control_section_id        Id of the section the control belongs to.
   * @param string $control_id                Id of the control to set a condition to.
   * @param array  $condition                 Render condition.
   */
  private function setElementorControlCondition( $control_section_id, $control_id, $condition ) {
    if ( array_key_exists( $control_section_id, $this->control_sections ) ) {
      if ( array_key_exists( $control_id, $this->control_sections[$control_section_id]['controls'] ) ) {
        $this->control_sections[$control_section_id]['controls'][$control_id]['args']['condition'] = $condition;
      }
    }
  }

  /**
   * Register actions
   * 
   * @since 1.0.0
   * 
   * @access protected
   */
  protected function addActions() {
    add_action( 'wp_enqueue_scripts', array( $this, 'enqueueStyles' ) );
    add_action( 'wp_enqueue_scripts', array( $this, 'enqueueScripts' ) );

    // Register Elementor widgets if the plugin is active
    if ( orokublocks()->pluginIsActive( 'elementor' ) ) {
      require_once orokublocks()->path . '/includes/classes/plugins/class-orokublocks-elementor-widget-base.php';
      require_once orokublocks()->path . '/includes/classes/plugins/class-orokublocks-elementor-widget.php';
      require_once orokublocks()->path . '/includes/classes/plugins/class-orokublocks-elementor-widget-pro.php';

      add_action( 'elementor/widgets/register', array( $this, 'registerElementorWidget' ) );
    }
  }

  /**
   * Enqueue styles
   * 
   * @since 1.0.0
   */
  public function enqueueStyles() {
    // Main styles
    wp_enqueue_style( 'orokublocks-widget-main-styles', orokublocks()->url . 'assets/widgets/css/widget.css', [], '1.0.0' );

    // Carousel styles
    wp_enqueue_style( 'orokublocks-widget-carousel-styles', orokublocks()->url . 'assets/widgets/css/vendor/glide.core.css', [], '1.0.0' );

    $widget_path_id = OrokuBlocks_Router::widgetPathIdGet( $this->widget_id );

    // Widget styles
    wp_enqueue_style(
      'orokublocks-' . $widget_path_id . '-styles',
      OrokuBlocks_Router::widgetUrlGet( $this->widget_id ) . '/css/' . $widget_path_id . '.css',
      [ 'orokublocks-widget-main-styles' ],
      '1.0.0'
    );
  }

  /**
   * Enqueue scripts
   * 
   * @since 1.0.0
   */
  public function enqueueScripts() {
    // Main script
    wp_enqueue_script(
      'orokublocks-widget-main-scripts',
      orokublocks()->url . 'assets/widgets/js/main.js',
      [
        'orokublocks-widget-arc-scripts',
        'orokublocks-widget-progressbar-scripts',
        'orokublocks-widget-countdown-scripts',
      ],
      '1.0.0',
      true
    );

    // Progress Bar
    wp_enqueue_script( 'orokublocks-widget-progressbar-scripts', orokublocks()->url . 'assets/widgets/js/vendor/xm_progressBar.js', [], '1.0.0', true );
    // Arc
    wp_enqueue_script( 'orokublocks-widget-arc-scripts', orokublocks()->url . 'assets/widgets/js/vendor/xm_arc.js', [], '1.0.0', true );
    // Countdown
    wp_enqueue_script( 'orokublocks-widget-countdown-scripts', orokublocks()->url . 'assets/widgets/js/vendor/xm_countdown.js', [], '1.0.0', true );

    // Carousel
    wp_enqueue_script( 'orokublocks-widget-carousel-scripts', orokublocks()->url . 'assets/widgets/js/vendor/glide.min.js', [], '1.0.0', true );

    // SVG script
    wp_enqueue_script( 'orokublocks-widget-svg-scripts', orokublocks()->url . 'assets/widgets/js/svg.js', [], '1.0.0', true );

    $widget_path_id = OrokuBlocks_Router::widgetPathIdGet( $this->widget_id );

    // Widget script
    wp_enqueue_script(
      'orokublocks-' . $widget_path_id . '-scripts',
      OrokuBlocks_Router::widgetUrlGet( $this->widget_id ) . '/js/' . $widget_path_id . '.js',
      [ 'orokublocks-widget-main-scripts' ],
      '1.0.0',
      true
    );
  }

  /**
   * Registers widget for Elementor
   * 
   * @since 1.0.0
   * 
   * @param object $widgets_manager     Elementor widgets manager instance.
   */
  public function registerElementorWidget( $widgets_manager ) {
    // Register widget if it is enabled
    if ( orokublocks()->widgetIsEnabled( $this->widget_id ) ) {
      $widget_path_id = OrokuBlocks_Router::widgetPathIdGet( $this->widget_id );

      require_once OrokuBlocks_Router::widgetPathGet( $this->widget_id ) . '/elementor/class-orokublocks-' . $widget_path_id . '-elementor-widget.php';

      $widget_classname = OrokuBlocks_Router::widgetClassNameGet( $this->widget_id, 'elementor' );

      $widgets_manager->register( new $widget_classname() );
    }
  }

  /**
   * Register Elementor control sections
   * 
   * @since 1.0.0
   * 
   * @param \Elementor\Widget_Base $widget        Elementor widget object.
   */
  public function registerElementorControlSections( $widget ) {
    foreach ( $this->control_sections as $control_section_id => $control_section ) {
      $widget->start_controls_section( $control_section_id . '_section', $control_section['args'] );

      foreach ( $control_section['controls'] as $control_id => $control ) {
        if ( $control['type'] === 'repeater' ) {
          $repeater = new \Elementor\Repeater();

          $repeater_controls = $control['controls'];

          foreach ( $repeater_controls as $repeater_control ) {
            if ( $repeater_control['type'] === 'sportspress_metrics' ) {
              $metrics = OrokuBlocks_Sportspress::metricsGet();

              $repeater_control['args']['options'] = $metrics;
              
              if ( is_array( $metrics ) && ( count( $metrics ) > 0 ) ) {
                $repeater_control['args']['default'] = array_keys( $metrics )[0];
              }

              $repeater->add_control( $repeater_control['id'], $repeater_control['args'] );
            } else {
              $repeater->add_control( $repeater_control['id'], $repeater_control['args'] );
            }
          }

          $repeater_control_args = $control['args'];
          $repeater_control_args['fields'] = $repeater->get_controls();

          $widget->add_control( $control_id, $repeater_control_args );
        } else {
          $widget->add_control( $control_id, $control['args'] );
        }
      }

      $widget->end_controls_section();
    }
  }

  /**
   * Return default widget options
   * 
   * @since 1.0.0
   * 
   * @return array      Default widget options.
   */
  public function getDefaultOptions() {
    return $this->defaults;
  }

  /**
   * Convert feature data value to template structure.
   * 
   * @since 1.0.0
   * 
   * @param array   $template_data        Widget template arguments.
   * @return array  $features             Template compatible value.
   */
  public function parseFeaturesData( $template_data ) {
    $feature_types = [ 'pros', 'cons' ];
    $feature_attributes = [ 'icon', 'status_tag_style', 'title' ];

    $features = [];

    foreach ( $feature_types as $feature_type ) {
      if ( count( $template_data[$feature_type] ) > 0 ) {
        $feature_data = [];

        $feature_data['features'] = $template_data[$feature_type];
        $feature_data['enabled'] = $feature_type === 'pros';

        foreach ( $feature_attributes as $feature_attribute ) {
          $feature_data_key = $feature_type . '_' . $feature_attribute;

          $feature_data[$feature_attribute] = $template_data[$feature_data_key];
        }

        $features[] = $feature_data;
      }
    }

    return $features;
  }

  /**
   * Convert Elementor control value to widget arguments structure
   * 
   * @since 1.0.0
   * 
   * @param string $control_type        Elementor control type.
   * @param mixed  $control_value       Elementor control value.
   * @return mixed $args_value          Argument compatible value.
   * 
   * @access private
   */
  private function parseElementorControlValue( $control_type, $control_value ) {
    $args_value = $control_value;

    if ( in_array( $control_type, [ 'url', 'media' ] ) ) {
      $args_value = $control_value['url'];
    } else if ( $control_type === 'switcher' ) {
      $args_value = $control_value === 'yes';
    }

    return $args_value;
  }

  /**
   * Convert Elementor control settings structure to widget arguments structure
   * 
   * @since 1.0.0
   * 
   * @param array   $control_settings       Elementor control setting values.
   * @return array  $widget_args            Widget compatible arguments.
   */
  public function parseElementorControlSettings( $control_settings ) {
    $widget_args = [];

    foreach ( $control_settings as $control_setting_id => $control_setting_value ) {
      if ( $control_setting_value !== null ) {
        foreach ( $this->control_sections as $control_section_id => $control_section ) {
          if ( array_key_exists( $control_setting_id, $control_section['controls'] ) ) {
            $control = $control_section['controls'][$control_setting_id];

            if ( $control['type'] === 'repeater' ) {
              $setting_value = array_map(
                function ( $control_values ) use ( $control ) {
                  $setting_item_values = [];

                  foreach ( $control_values as $control_value_id => $control_value ) {
                    foreach ( $control['controls'] as $repeater_control ) {
                      if ( $repeater_control['id'] === $control_value_id ) {
                        $setting_item_values[$control_value_id] = $this->parseElementorControlValue( $repeater_control['type'], $control_value );
                      }
                    }
                  }

                  return $setting_item_values;
                },
                $control_setting_value
              );
            } else {
              $setting_value = $this->parseElementorControlValue( $control['type'], $control_setting_value );
            }

            $widget_args[$control_setting_id] = $setting_value;
          }
        }
      }
    }

    return $widget_args;
  }

  /**
   * Returns template version
   * 
   * @since 1.0.0
   * 
   * @see widgets/widget_path_id/template/widget_path_id-vn.php     For vn $args supported parameters.
   * 
   * @param string  $version      Template version.
   * @param array   $args         Template parameters.
   * @return string $template     HTML template of specified version.
   */
  public function getTemplate( $version = '', $args = [] ) {
    ob_start();

    /**
     * Scoring Rating
     */
    orokublocks()->includeWidget( $this->widget_id, $version, $args );

    $template = ob_get_clean();

    return $template;
  }
}