<?php
/*
  File: Theme Support and Customizer
  Comments: Add all your Theme Support and Setup here
*/
if( ! defined( 'ABSPATH' ) ) exit;

new customizer();
class customizer {

    /* 
        Constructor 
    */
    function __construct() {

        if ( is_admin() ) {
            require get_template_directory() . '/inc/customizer_ff.php';
        }

        $this->customizer();
        
        // deprecated loginscreen
        if (get_theme_mod('custom_login_style', false)) {
            require get_template_directory() . '/inc/deprecated/login.php';
        }
    }

    /*
        add customizer options (theme_mods)
    */
    public function customizer() {
        // if (!\vc\helper::is_active_plugin('greyd_tp_management/init.php')) return;
        
        add_action( 'customize_preview_init', array($this, 'customize_preview_js') );
        add_action( 'customize_controls_enqueue_scripts', array($this, 'customize_controls_js') );
        add_action( 'customize_register', array($this, 'theme_settings_extension') );
        add_action( 'customize_register', array($this, 'theme_settings_extension_process'), 99 );
        add_filter( 'the_content', array($this, 'customizer_page_content'));
    }

    /* enqueue script to preview page */
    public function customize_preview_js() {
        global $config;
        // css
        wp_enqueue_style( 'previewer', get_template_directory_uri() . '/assets/css/customizer_preview.css' );
        // wp_process_style('default_style', get_template_directory().'/assets/css/customizer_preview.css');
        // js
        wp_enqueue_script( 'customizer_shared', get_template_directory_uri() . '/assets/js/customizer_shared.js', array( 'customize-preview', 'jquery' ), $config->theme_version, true );
        wp_add_inline_script('customizer_shared', 'var mods = '.json_encode(processor::$root).'; var themeversion = "'.$config->theme_version.'";', 'before');
        wp_add_inline_script('customizer_shared', 'var gfonts = '.json_encode(processor::$gfontsInfo).';', 'after');
        wp_enqueue_script( 'customizer', get_template_directory_uri() . '/assets/js/customizer.js', array( 'customize-preview', 'jquery' ), $config->theme_version, true );
        $wordings = array(
            "nothing"           => _x('Keine Auswahl', 'small', 'core'),
            "disc"              => _x('• gefüllter Kreis', 'small', 'core'),
            "circle"            => _x('◦ offener Kreis', 'small', 'core'),
            "square"            => _x('▪ gefülltes Quadrat', 'small', 'core'),
            "no_symbol"         => _x('kein Symbol', 'small', 'core'),
            "decimal"           => _x('numerisch (1. 2. ...)', 'small', 'core'),
            "decimal_leading_zero" => _x('numerisch mit Null (01. 02. ...)', 'small', 'core'),
            "lower_roman"       => _x('römisch klein (i. ii. ...)', 'small', 'core'),
            "upper_roman"       => _x('römisch groß (I. II. ...)', 'small', 'core'),
            "lower_greek"       => _x('griechisch klein (α. β. ...)', 'small', 'core'), 
            "armenian"          => _x('armenisch (Ա. Բ. ...)', 'small', 'core'), 
            "georgian"          => _x('georgisch (ა. ბ. ...)', 'small', 'core'), 
            "lower_alpha"       => _x('alphabetisch klein (a. b. ...)', 'small', 'core'), 
            "upper_alpha"       => _x('alphabetisch groß (A. B. ...)', 'small', 'core'), 
            "no_num"            => _x('keine Nummerierung', 'small', 'core'),
        );
        wp_add_inline_script( 'customizer', 'var previewer_wordings = '.json_encode($wordings).';', 'before' );
    }

    /* enqueue script to Customizer controls */
    public function customize_controls_js() {
        global $config;
        // css
        wp_enqueue_style( 'customizer_admin_css', get_template_directory_uri() . '/assets/css/customizer.css' );
        // js
        wp_enqueue_script( 'customizer_shared', get_template_directory_uri() . '/assets/js/customizer_shared.js', array( 'customize-preview', 'jquery' ), $config->theme_version, true );
        wp_add_inline_script('customizer_shared', 'var mods = '.json_encode(processor::$root).'; var themeversion = "'.$config->theme_version.'";', 'before');
        wp_add_inline_script('customizer_shared', 'var gfonts = '.json_encode(processor::$gfontsInfo).';', 'after');
        wp_enqueue_script( 'customizer_admin', get_template_directory_uri() . '/assets/js/customizer_admin.js', array( 'customize-controls', 'jquery' ), $config->theme_version, true );
        $wordings = array(
            "info_text"         => __("Im Customizer definierst du das grundlegende Design deiner Website. Alle Änderungen siehst du direkt rechts in der Vorschau. Die Aufbauseite enthält unten außerdem ein Anwendungsbeispiel, in der du die einzelnen Website-Elemente im Zusammenspiel sehen kannst.", 'core'),
            "template_created"  => __("Template '%1s' (id %2s) erstellt.", 'core'),
            "enter_value"       => __("Bitte geben Sie einen neuen Wert für '%s' ein", 'core'),
            "used_by"           => __("Verwendet von <strong>%s Einstellungen</strong> ▾<br>", 'core'),
            "font"              => __("Schrift", 'core'),
            "custom_font"       => [
                "busy"              => __("Es wird gerade eine Datei hochgeladen. Bitte warten.", 'core'),
                "nothing"           => __("Keine Auswahl", 'core'),
                "no_script"         => __("Fontscript nicht gefunden.", 'core'),
                "no_data"           => __("Keine Daten.", 'core'),
                "too_many"          => __("Bitte nur eine Datei auswählen.", 'core'),
                "too_big"           => __("Die maximale Dateigröße beträgt 10MB. Bitte eine kleinere Datei auswählen.", 'core'),
                "no_zip"            => __("Bitte eine korrekte .zip Datei auswählen.", 'core'),
                "no_font"           => __("'%s' enthält keine Schriftart.", 'core'),
                "duplicate"         => __("Die Schriftfamilie '%s' ist bereits installiert.", 'core'),
                "success_install"   => __("'%s' erfolgreich installiert.", 'core'),
                "enter_name"        => __("Bitte geben Sie einen neuen Namen für die individuelle Schrift ein.", 'core'),
                "success_edit"      => __("'%s' erfolgreich umbenannt.", 'core'),
                "confirm_delete"    => __("Individuelle Schrift '%s' dauerhaft löschen?", 'core'),
                "success_delete"    => __("'%s' erfolgreich gelöscht.", 'core'),
                "failed"            => __("Fehlgeschlagen.", 'core'),
                "aborted"           => __("Abgebrochen.", 'core'),
            ],
            "colors"            => [
                "alpha"     => __("Alpha: %s", 'core'),
                "color11"   => __('Primär', 'core'),
                "color12"   => __('Sekundär', 'core'),
                "color13"   => __('Alternative', 'core'),
                "color31"   => __('Sehr dunkel', 'core'),
                "color21"   => __('Dunkel', 'core'),
                "color32"   => __('Leicht dunkel', 'core'),
                "color22"   => __('Leicht hell', 'core'),
                "color33"   => __('Hell', 'core'),
                "color23"   => __('Sehr hell', 'core'),
                "color41"   => __('Hinweismeldung Dunkel', 'core'),
                "color51"   => __('Hinweismeldung Hell', 'core'),
                "color42"   => __('Erfolgsmeldung Dunkel', 'core'),
                "color52"   => __('Erfolgsmeldung Hell', 'core'),
                "color43"   => __('Fehlermeldung Dunkel', 'core'),
                "color53"   => __('Fehlermeldung Hell', 'core'),
                "color61"   => __('Schwarz', 'core'),
                "color62"   => __('Weiß', 'core'),
                "color63"   => __('Transparent', 'core'),
            ]
        );
        wp_add_inline_script( 'customizer_admin', 'var customizer_wordings = '.json_encode($wordings).';', 'before' );
    }

    /* preview page content */
    public function customizer_page_content($content) {
        if (is_customize_preview()) {
            if (isset($_GET['tp_preview_page'])) {
                // make shortcodes
                $sc = '[vc_row][vc_column]
                            [preview_header]
                            [preview_fonts]
                            [preview_colors]
                            [preview_body]
                            [preview_headlines]
                            [preview_buttons]
                            [preview_links]
                            [preview_forms]
                            [preview_messages]
                            [preview_tables]
                            [preview_usage]
                        [/vc_column][/vc_row]
                        [vc_row row_type="row_xxxl" 
                                override_type="override_sm,override_md,override_lg,override_xl" 
                                override_gutter="override_sm,override_md,override_lg,override_xl"][vc_column]
                            [preview_grid]
                        [/vc_column][/vc_row]';
                // translate to user locale
                global $l10n;
                if (isset($l10n['core'])) $backup = $l10n['core'];
                load_textdomain('core', get_template_directory().'/languages/'.get_user_locale().'.mo');
                $content = do_shortcode($sc);
                if (isset($backup)) $l10n['core'] = $backup;
            }
        }
        return $content;
    }

    /* customizer settings */
    public function theme_settings_extension($wp_customize) {
        // make panels for settings/controls
        //
        // Grundeinstellungen
        $wp_customize->add_panel( 'panel_settings', array(
            'title'    => __( 'Basics', 'core' ),
            'priority' => 1,
        ) ); 
        $wp_customize->get_section('title_tagline')->title = __( 'Titel', 'core' );
        $wp_customize->get_section('title_tagline')->panel = 'panel_settings';
        $wp_customize->get_control('blogname')->label = __( 'Website Titel', 'core' );
        $wp_customize->get_control('blogdescription')->label = __( 'Untertitel', 'core' );
        $wp_customize->get_control('header_text')->label = __( 'Titel der Website im Header anzeigen', 'core' );
        $wp_customize->get_control('header_text')->description = __( 'Solange kein Logo definiert ist, wird der Titel der Website im Header angezeigt.', 'core' );
        $wp_customize->add_section('section_brand_logo', array(
            'title'    => __( 'Logo', 'core' ),
            'panel'    => 'panel_settings',
        ) );
        $wp_customize->get_control('custom_logo')->section = 'section_brand_logo';
        $wp_customize->get_control('site_icon')->section = 'section_brand_logo';
        $wp_customize->get_control('site_icon')->label = __( 'Website Icon', 'core' );
        $wp_customize->get_control('site_icon')->description = __( "<p>Website Icons erscheinen in Browser-Tabs, Lesezeichenleisten und innerhalb der WordPress Mobile Apps. Lade hier eins hoch!</p><p>Website Icons sollten quadratisch und mindestens <strong>512 × 512</strong> Pixel groß sein.</p>", 'core' );
		$wp_customize->add_section('section_brand_fonts', array(
            'title'    => __( 'Schriften', 'core' ),
            'panel'    => 'panel_settings',
        ) );
		$wp_customize->add_section('section_brand_colors', array(
            'title'    => __( 'Farben', 'core' ),
            'panel'    => 'panel_settings',
        ) );
		$wp_customize->add_section('section_brand_basics', array(
            'title'    => __( 'Grundeinstellungen', 'core' ),
            'panel'    => 'panel_settings',
        ) );

        //
        // Navigation
        $wp_customize->add_panel( 'panel_navigation', array(
            'title'    => __( 'Navigation', 'core' ),
            'priority' => 2,
        ) ); 
		$wp_customize->add_section('section_header', array(
            'title'    => __( 'Header', 'core' ),
            'panel'    => 'panel_navigation',
        ) );
		$wp_customize->add_section('section_navi', array(
            'title'    => __( 'Hauptmenü', 'core' ),
            'panel'    => 'panel_navigation',
        ) );
        $wp_customize->add_section('section_meta', array(
            'title'    => __( 'Metamenü', 'core' ),
            'panel'    => 'panel_navigation',
            'type'     => (has_nav_menu('meta-menu')) ? '' : 'hidden'
        ) );

		$wp_customize->add_section('section_navi_header', array(
            'title'    => __( 'Header', 'core' ),
            'panel'    => 'panel_navigation',
        ) );
		$wp_customize->add_section('section_navi_header_offcanvas', array(
            'title'    => __( 'Off-Menü', 'core' ),
            'panel'    => 'panel_navigation',
        ) );

		$wp_customize->add_section('section_dropdown', array(
            'title'    => __( 'Dropdowns', 'core' ),
            'panel'    => 'panel_navigation',
        ) );
		$wp_customize->add_section('section_footer', array(
            'title'    => __( 'Footer', 'core' ),
            'panel'    => 'panel_navigation',
        ) );
        
		$wp_customize->add_section('section_navi_footer', array(
            'title'    => __( 'Footer', 'core' ),
            'panel'    => 'panel_navigation',
        ) );
		$wp_customize->add_section('section_navi_header_sec', array(
            'title'    => __( 'Zweiter Header', 'core' ),
            'panel'    => 'panel_navigation',
        ) );
		$wp_customize->add_section('section_navi_header_sec_offcanvas', array(
            'title'    => __( 'Zweites Off-Menü', 'core' ),
            'panel'    => 'panel_navigation',
        ) );
        
        //
        // Elemente
        $wp_customize->add_panel( 'panel_elements', array(
            'title'    => __( 'Elemente', 'core' ),
            'priority' => 3,
        ) );
		$wp_customize->add_section('section_body', array(
            'title'    => __( 'Text', 'core' ),
            'panel'    => 'panel_elements',
        ) );
		$wp_customize->add_section('section_headlines', array(
            'title'    => __( 'Überschriften', 'core' ),
            'panel'    => 'panel_elements',
        ) );
		$wp_customize->add_section('section_buttons', array(
            'title'    => __( 'Buttons', 'core' ),
            'panel'    => 'panel_elements',
        ) );
		$wp_customize->add_section('section_links', array(
            'title'    => _x( 'Links', 'web', 'core' ),
            'panel'    => 'panel_elements',
        ) );
		$wp_customize->add_section('section_forms', array(
            'title'    => __( 'Formularfelder', 'core' ),
            'panel'    => 'panel_elements',
        ) );
		$wp_customize->add_section('section_messages', array(
            'title'    => __( 'Benachrichtigungen', 'core' ),
            'panel'    => 'panel_elements',
        ) );
		$wp_customize->add_section('section_tables', array(
            'title'    => __( 'Tabellen', 'core' ),
            'panel'    => 'panel_elements',
        ) );
        
        //
        // Weiteres
        $wp_customize->add_panel( 'panel_more', array(
            'title'    => __( 'Erweitert', 'core' ),
            'priority' => 9999,
        ) ); 
		$wp_customize->add_section('section_features', array(
            'title'    => __( 'Features', 'core' ),
            'panel'    => 'panel_more',
        ) );
		$wp_customize->add_section('section_modules', array(
            'title'    => __( 'Module', 'core' ),
            'panel'    => 'panel_more',
        ) );
        $wp_customize->add_section( 'section_grid', array(
            'title'    => __( 'Seitenraster', 'core' ),
            'panel'    => 'panel_more',
        ) ); 
        $wp_customize->get_section('custom_css')->panel = 'panel_more';
        $wp_customize->get_section('custom_css')->title = __( 'Globales CSS', 'core' );

    }
    public function theme_settings_extension_process($wp_customize) {
        //
        // remove some more default panels
        $wp_customize->remove_section("static_front_page");
        $wp_customize->get_panel('nav_menus')->active_callback = '__return_false';
        //
        // add vars to sections
        // $translations = array();
        processor::process_defaults();
        foreach (processor::$root as $var => $val) {

            $val = controls::process_control($val);
            // get all translation strings
            // if (isset($val['label'])) array_push($translations, $val['label']);
            // if (isset($val['description'])) array_push($translations, $val['description']);
            // if (isset($val['lbl'])) array_push($translations, $val['lbl']);
            // if (isset($val['input_attrs']['lbl'])) array_push($translations, $val['input_attrs']['lbl']);
            // if (isset($val['choices'])) {
            //     foreach ($val['choices'] as $key => $title) {
            //         if (is_array($title) && isset($title['label']))
            //             array_push($translations, $title['label']);
            //         else array_push($translations, $title);
            //     }
            // }

            $this->add_setting($wp_customize, array(
                'transport'   => $val['transport'],
                'priority'    => $val['priority'],
                'section'     => $val['section'],
                'name'        => $val['mod'],
                'label'       => $val['label'],
                'description' => $val['description'],
                'type'        => $val['type'],
                'default'     => $val['value'],
                'input_attrs' => $val['input_attrs'],
                'choices'     => $val['choices'],
                'class'       => $val['class'],
            ) );

        }
        
        // echo translation strings and exit
        // $translations = array_filter(array_unique($translations));
        // $strings = array();
        // foreach ($translations as $index => $translation) {
        //     array_push($strings, "__('".$translation."', 'core')");
        // }
        // debug($strings);
        // die();
    }

    public function add_setting($wp_customize, $sets) {

        // // sanitize
        // if (empty($sets['label'])) $sets['label'] = "";
        // if (empty($sets['description'])) $sets['description'] = "";
        // if (empty($sets['transport'])) $sets['transport'] = "postMessage";
        
        // make setting
        if ($sets['type'] != 'separator' &&
            $sets['type'] != 'sub_separator' &&
            $sets['type'] != 'info' &&
            $sets['type'] != 'group' &&
            $sets['type'] != 'button') {
            $wp_customize->add_setting( $sets['name'], array(
                'default'     => $sets['default'],
                'transport'   => $sets['transport'],
            ) );
        }
        // make control
        if ($sets['type'] == 'checkbox' ||
            $sets['type'] == 'radio' ||
            $sets['type'] == 'select' ||
            $sets['type'] == 'text' ||
            $sets['type'] == 'textarea') {
            if (empty($sets['choices'])) $sets['choices'] = array();
            $wp_customize->add_control( $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
                'type'        => $sets['type'],
                'choices'     => $sets['choices'],
            ) );
        }
        // custom
        elseif ($sets['type'] == 'range') {
            if (empty($sets['input_attrs'])) $sets['input_attrs'] = array();
            $wp_customize->add_control( new Customize_Range_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
                'input_attrs' => $sets['input_attrs'],
            ) ) );
        }
        elseif ($sets['type'] == 'image') {
            $wp_customize->add_control( new WP_Customize_Image_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
            ) ) );
        }
        // font
        elseif ($sets['type'] == 'fontfamily') {
            $wp_customize->add_control( new Customize_Fontfamily_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
            ) ) );
        }
        elseif ($sets['type'] == 'ffselect') {
            $wp_customize->add_control( new Customize_FFselect_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
            ) ) );
        }
        // color
        elseif ($sets['type'] == 'color') {
            $wp_customize->add_control( new WP_Customize_Color_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
            ) ) );
        }
        elseif ($sets['type'] == 'colselect') {
            $wp_customize->add_control( new Customize_Colselect_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
            ) ) );
        }
        elseif ($sets['type'] == 'acolor') {
            $wp_customize->add_control( new Customize_Alpha_Color_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
                'show_opacity'=> false,
                //'palette'     => $sets['palette'],
            ) ) );
        }
        // shadow
        elseif ($sets['type'] == 'shadow') {
            $wp_customize->add_control( new Customize_Shadow_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
            ) ) );
        }
        
        // preset-picker
        elseif ($sets['type'] == 'preset') {
            $wp_customize->add_control( new Customize_Preset_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
                'choices'     => $sets['choices'],
                'input_attrs' => $sets['input_attrs'],
            ) ) );
        }
        
        // controls without setting
        elseif ($sets['type'] == 'info') {
            $wp_customize->add_control( new Customize_Info_Control( $wp_customize, $sets['name'], array(
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
                'input_attrs' => $sets['input_attrs'],
            ) ) );
        }
        elseif ($sets['type'] == 'separator') {
            $wp_customize->add_control( new Customize_Separator_Control( $wp_customize, $sets['name'], array(
                'settings'    => array(),
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
            ) ) );
        }
        elseif ($sets['type'] == 'sub_separator') {
            $wp_customize->add_control( new Customize_Subseparator_Control( $wp_customize, $sets['name'], array(
                'settings'    => array(),
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
            ) ) );
        }
        elseif ($sets['type'] == 'group') {
            $wp_customize->add_control( new Customize_Group_Control( $wp_customize, $sets['name'], array(
                'settings'    => array(),
                'priority'    => $sets['priority'],
                'label'       => $sets['label'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
                'input_attrs' => $sets['input_attrs'],
            ) ) );
        }
        elseif ($sets['type'] == 'button') {
            if (empty($sets['input_attrs'])) $sets['input_attrs'] = array();
            if (!empty($sets['label'])) $sets['input_attrs']['value'] = $sets['label'];
            if (!empty($sets['class'])) $sets['input_attrs']['class'] = 'button button-'.$sets['class'];
            if (!empty($sets['input_attrs']['menu'])) {
                $menu_name = $sets['input_attrs']['menu'];
                $locations = get_nav_menu_locations();
                if (isset($locations[$menu_name])) {
                    $menu_id = $locations[$menu_name];
                    $sets['input_attrs']['menu'] = $menu_id;
                }
                else $sets['input_attrs']['menu'] = "";
            }
            if (!empty($sets['input_attrs']['template'])) {
                $template_name = $sets['input_attrs']['template'];
                $template = get_page_by_path( $template_name, OBJECT, 'dynamic_template' );
                $template_id = (!$template) ? "" : $template->ID;
                $sets['input_attrs']['template_id'] = $template_id;
            }
            $wp_customize->add_control( $sets['name'], array(
                'settings'    => array(),
                'priority'    => $sets['priority'],
                'description' => $sets['description'],
                'section'     => $sets['section'],
                'type'        => $sets['type'],
                'input_attrs' => $sets['input_attrs'],
            ) );
        }
    }

    
}

//
// custom control classes
//
if (class_exists('WP_Customize_Control')) {

    class Customize_Separator_Control extends WP_Customize_Control {
        public $type = 'separator';
        public function render_content() {
            $head = "";
            if (!empty($this->label)) $head = "<span class='customize-control-title'>".esc_html($this->label)."</span>";
            $description = "";
            if (!empty($this->description)) $description = "<span class='description customize-control-description'>".$this->description."</span>";

            echo "$head
                  <div class='customize-control-sep'></div>
                  $description";
        }
    }
    class Customize_Subseparator_Control extends WP_Customize_Control {
        public $type = 'sub_separator';
        public function render_content() {
            $head = "";
            if (!empty($this->label)) $head = "<span class='customize-control-title'>".esc_html($this->label)."</span>";
            $description = "";
            if (!empty($this->description)) $description = "<span class='description customize-control-description'>".$this->description."</span>";

            echo "$head
                  <div class='customize-control-sep'></div>
                  $description";
        }
    }    
    class Customize_Group_Control extends WP_Customize_Control {
        public $type = 'group';
        public function render_content() {
            $head = "";
            if (!empty($this->label)) $head = esc_html($this->label);
            $description = "";
            if (!empty($this->description)) $description = "data-description='".$this->description."'";

            $children = $this->input_attrs['children'];
            echo "<span class='button' data-state='on' data-children='".$children."' data-head='".$head."' $description></span>";
        }
    }
    class Customize_Info_Control extends WP_Customize_Control {
        public $type = 'info';
        public function render_content() {
            
            // vars
            $atts = [
                'styling'   => $this->input_attrs
            ];
            // label and description
            if (!empty($this->label))
                $atts['above'] = esc_html($this->label);
            if (!empty($this->description)){
                $atts['text'] = esc_html($this->description);
                echo \vc\helper::render_info_box($atts);
            }
        }
    }

    class Customize_Range_Control extends WP_Customize_Control {
        public $type = 'custom_range';
        public function render_content() {
            $head = "";
            if (!empty($this->label)) $head = "<span class='customize-control-title'>".esc_html($this->label)."</span>";
            $description = "";
            if (!empty($this->description)) $description = "<span class='description customize-control-description'>".$this->description."</span>";

            $value = esc_attr($this->value());
            $lbl = $this->input_attrs['lbl'];
            $unit = isset($this->input_attrs['unit']) ? $this->input_attrs['unit'] : "";
            $atts = "";
            if (isset($this->input_attrs['min']) && isset($this->input_attrs['max']) && isset($this->input_attrs['step']))
                $atts = "min='".esc_attr($this->input_attrs['min'])."' max='".esc_attr($this->input_attrs['max'])."' step='".esc_attr($this->input_attrs['step'])."' ";
            $link = $this->get_link();

            echo "<label>
                    $head
                    <div class='cs-range-value' data-lbl='$lbl' data-unit='$unit'>$lbl $value$unit</div>
                    <input data-input-type='range' type='range' style='width:100%' value='$value' $atts $link />
                    $description
                </label>";
        }
    }

    class Customize_Fontfamily_Control extends WP_Customize_Control {
        public $type = 'fontfamily';
        public function render_content() {
            $input_id = '_customize-input-'.$this->id;
            $description_id = '_customize-description-'.$this->id;
            $describedby_attr = (!empty($this->description)) ? 'aria-describedby="'.esc_attr($description_id).'" ' : '';
            $link_attr = $this->get_link();
            
            $val = $this->value();
            $tmp = explode(':', $val);
            $val = $tmp[0];
            $val_weights = array();
            if (count($tmp) > 1) {
                $val_weights = explode(',', $tmp[1]);
            }

            $src = "";
            $display_websafe = "none";
            $display_google = "none";
            $display_custom = "none";
            $display_custom_edit = "none";
            if (in_array($val, processor::$wfonts)) {
                $display_websafe = "block";
                $src = "websafe";
            }
            if (in_array($val, processor::$gfonts) && !in_array($val, processor::$cfonts)) {
                $display_google = "block";
                $src = "google";
            }
            if (in_array($val, processor::$cfonts)) {
                $display_custom = "block";
                $display_custom_edit = "block";
                $src = "custom";
            }


            // original select with label and description
            if (!empty($this->label))
                echo '<label for="'.esc_attr($input_id).'" class="customize-control-title">'.esc_html($this->label).'</label>';
            if (!empty($this->description))
                echo '<span id="'.esc_attr($description_id).'" class="description customize-control-description">'.$this->description.'</span>';
            // actual value
            echo "<input type='hidden' id='".esc_attr($input_id)."' ".$describedby_attr.$link_attr." value='".$this->value()."' />";

            // select source
            echo '<div id="ffsource-'.$this->id.'">';
                echo '<select id="input-ffsource-'.$this->id.'">';
                    echo '<option value="">'._x('Schriftquelle auswählen', 'small', 'core').'</option>';
                    echo '<option value="websafe" '.selected($src, 'websafe', false).'>'._x('websichere Schriften', 'small', 'core').'</option>';
                    echo '<option value="google" '.selected($src, 'google', false).'>'._x('Google Fonts', 'small', 'core').'</option>';
                    echo '<option value="custom" '.selected($src, 'custom', false).'>'._x('individuelle Schriften', 'small', 'core').'</option>';
                echo '</select>';
            echo '</div>';

            // select websafe fonts
            echo '<div id="ffwebsafe-'.$this->id.'" class="customize-control-ff-select" style="display:'.$display_websafe.'">';
                echo '<span id="description-ffwebsafe-'.$this->id.'" class="description customize-control-description">
                        <a href="https://www.w3schools.com/CSSref/css_websafe_fonts.asp" target="_blank">'.__('Websichere Schriften', 'core').'</a>
                    </span>';
                echo '<select id="input-ffwebsafe-'.$this->id.'">';
                    echo '<option value="">'._x('Schriftfamilie auswählen', 'small', 'core').'</option>';
                foreach (processor::$wfonts as $value => $label) {
                    echo '<option value="'.esc_attr($value).'" '.selected($val, $value, false).'>'.$label.'</option>';
                }
                echo '</select>';
            echo '</div>';

            // select google fonts
            echo '<div id="ffgoogle-'.$this->id.'" class="customize-control-ff-select" style="display:'.$display_google.'">';
                echo '<span id="description-ffgoogle-'.$this->id.'" class="description customize-control-description">
                        <a href="https://www.w3schools.com/howto/howto_google_fonts.asp" target="_blank">'.__('Google Fonts', 'core').'</a>
                    </span>';
                echo '<select id="input-ffgoogle-'.$this->id.'">';
                    echo '<option value="">'._x('Schriftfamilie auswählen', 'small', 'core').'</option>';
                    foreach (processor::$gfonts as $value => $label) {
                        echo '<option value="'.esc_attr($value).'" '.selected($val, $value, false).'>'.$label.'</option>';
                    }
                echo '</select>';

                echo '<div id="description-ffgoogle-weights-'.$this->id.'" style="margin: 10px 0 10px 0">';
                    echo '<span class="description customize-control-description">'.__('Schriftschnitte laden:', 'core').'</span>';
                    $weigths = array(
                        '100'       => _x( '100 - extra thin', 'small', 'core'),
                        '100italic' => _x( '100 - extra thin italic', 'small', 'core'),
                        '200'       => _x( '200 - thin', 'small', 'core'),
                        '200italic' => _x( '200 - thin italic', 'small', 'core'),
                        '300'       => _x( '300 - light', 'small', 'core'),
                        '300italic' => _x( '300 - light italic', 'small', 'core'),
                        'regular'   => _x( '400 - regular', 'small', 'core'),
                        'italic'    => _x( '400 - regular italic', 'small', 'core'),
                        '500'       => _x( '500 - medium', 'small', 'core'),
                        '500italic' => _x( '500 - medium italic', 'small', 'core'),
                        '600'       => _x( '600 - semi-bold', 'small', 'core'),
                        '600italic' => _x( '600 - semi-bold italic', 'small', 'core'),
                        '700'       => _x( '700 - bold', 'small', 'core'),
                        '700italic' => _x( '700 - bold italic', 'small', 'core'),
                        '800'       => _x( '800 - fat', 'small', 'core'),
                        '800italic' => _x( '800 - fat italic', 'small', 'core'),
                        '900'       => _x( '900 - extra-fat', 'small', 'core'),
                        '900italic' => _x( '900 - extra-fat italic', 'small', 'core'),
                    );
                    foreach ($weigths as $value => $label) {
                        $checked = (in_array($value, $val_weights)) ? 'checked="checked"' : "";
                        echo '<label for="input-ffgoogle-weight-'.$this->id.'-'.$value.'">
                                <input type="checkbox" id="input-ffgoogle-weight-'.$this->id.'-'.$value.'" name="'.$value.'" '.$checked.'></input>
                                <span>'.$label.'</span>
                            </label>';
                    }
                echo '</div>';

                echo '<div id="warning-ffgoogle-dsgvo-'.$this->id.'" style="'.$display_google.'">';
                    $atts = array(
                        'styling' => 'info',
                        'text' => sprintf(
                            __("<b>Tipp:</b> Für DSGVO-konforme Websites empfehlen wir dir, externe Schriften (z.B. Google Fonts) als individuelle Schrift hochzuladen. <a %s>Hier gehts zum Tutorial Video</a>.", 'core' ),
                            "href=\"".__("https://helpcenter.greyd.de/customizer/#CustomFont", 'core')."\" target=\"_blank\""
                        ),
                    );
                    echo \vc\helper::render_info_box($atts);
                echo '</div>';

                $warn = "display:none";
                if (count($val_weights) > 2) $warn = "display:block";
                echo '<div id="warning-ffgoogle-weight-'.$this->id.'" style="'.$warn.'">';
                    $atts = array(
                        'styling' => 'info',
                        'text' => sprintf(
                            __("<b>Hinweis:</b> Bei Google Fonts können sich zu viele Schriftschnitte negativ auf den Pagespeed deiner Seite auswirken.", 'core' )."<br><br>".
                            __("<b>Tipp:</b> Lade dir die gewünschte Schrift bei <a %s>Google Fonts</a> herunter und binde sie in der GREYD.SUITE als individuelle Schrift ein.", 'core' ),
                            "href=\"https://fonts.google.com/\" target=\"_blank\""
                        ),
                    );
                    echo \vc\helper::render_info_box($atts);
                echo '</div>';

            echo '</div>';

            // upload custom font
            echo '<div id="ffcustom-'.$this->id.'" class="customize-control-ff-select" style="display:'.$display_custom.'">';
                echo '<select id="input-ffcustom-'.$this->id.'">';
                    echo '<option value="">'._x('Schriftfamilie auswählen', 'small', 'core').'</option>';
                foreach (processor::$cfonts as $value => $label) {
                    echo '<option value="'.esc_attr($value).'" '.selected($val, $value, false).'>'.$label.'</option>';
                }
                    echo '<option value="load">'._x('Schriftfamilie hochladen', 'small', 'core').'</option>';
                echo '</select>';
                echo '<div class="customize-control-ff-custom">';

                    $ajax_action    = 'greyd_custom_font_upload';
                    $uploads        = wp_upload_dir();
                    $uploadpath     = $uploads['basedir']."/greyd_tp/custom_fonts";

                    // $uploadscript = get_template_directory_uri()."/inc/customizer_ff.php";
                    $ajax_url = admin_url( 'admin-ajax.php' );

                    echo '<form id="form-ffupload-'.$this->id.'" action="'.$ajax_url.'" method="post">
                        <input type="hidden" name="uploadpath" value="'.$uploadpath.'" required>
                        <input type="hidden" name="ajax_action" value="'.$ajax_action.'">';
                        wp_nonce_field($ajax_action);
                        echo '<span class="description customize-control-description" style="margin-top:10px;">'.__('Schrift benennen', 'core').'</span>
                        <input type="text" name="name_full" placeholder="'.__('Schriftname mit Alternativen', 'core').'" value="" required>
                        <span class="description customize-control-description" style="margin-top:10px;">'.__('Schrift hochladen', 'core').'</span>
                        <input type="file" name="font" accept="application/zip" value="" required>
                        <input class="button button-secondary" type="button" value="'.__('Datei wählen', 'core').'">
                        <input class="button button-primary" type="submit" name="uploadFont" value="'.__('Schrift hochladen', 'core').'" style="margin-bottom:5px;"><br>
                        <span class="info-ffupload">'.__('Keine Datei gewählt', 'core').'</span><br>
                        <span class="progress-ffupload"></span><br>
                        <span class="description customize-control-description">'.__('Anleitung', 'core').'</span>
                        <small style="display:block;line-height:130%;">'.__(
                            'Lade eine zip-Datei hoch. Darin müssen sich eine CSS-Datei und die jeweiligen Schriftschnitte befinden. Die CSS-Datei muss genauso heißen, wie deine Schriftfamilie (z.B.&nbsp;myFont.css).<br>Innerhalb der Datei muss die Schriftfamilie mit dem gleichen Namen definiert sein und auf die jeweiligen Schriftschnitte verweisen (z.B.&nbsp;font-family: "myFont";).<br>Die Benennung der Schriftfamilie oben muss mit dem Namen im CSS übereinstimmen, kann aber zusätzlich Alternativen beinhalten, die als Fallback dienen (z.B.&nbsp;myFont, Helvetica, sans-serif).'
                            , 'core').'
                        </small>
                    </form>';
                echo '</div>';
                echo '<div class="customize-control-ff-custom" style="display:'.$display_custom_edit.'">';
                    echo '<span class="info-ffedit" style="display:block"></span>';
                    echo '<input id="input-ffedit-'.$this->id.'" class="button button-secondary" style="margin-right: 4px;" type="button" value="'.__('Schrift bearbeiten', 'core').'" />';
                    echo '<input id="input-ffdelete-'.$this->id.'" class="button button-danger" type="button" value="'.__('Schrift löschen', 'core').'" />';
                echo '</div>';
            echo '</div>';

            // log
            echo '<span id="_customize-log-'.$this->id.'" class="customize-control-log"></span>';
        }
    }
    class Customize_FFselect_Control extends WP_Customize_Control {
        public $type = 'ffselect';
        public function render_content() {
            $input_id = '_customize-input-'.$this->id;
            $description_id = '_customize-description-'.$this->id;
            $describedby_attr = (!empty($this->description)) ? 'aria-describedby="'.esc_attr($description_id).'" ' : '';
            $link_attr = $this->get_link();

            $choices = array( 
                'fontFamily1' => __('Schrift', 'core').' 1 - '.get_theme_mod('fontFamily1', ''), 
                'fontFamily2' => __('Schrift', 'core').' 2 - '.get_theme_mod('fontFamily2', ''), 
                'fontFamily3' => __('Schrift', 'core').' 3 - '.get_theme_mod('fontFamily3', ''), 
                // 'custom' => 'Custom' 
            );
            $val = $this->value();

            // original select with label and description
            if (!empty($this->label))
                echo '<label for="'.esc_attr($input_id).'" class="customize-control-title">'.esc_html($this->label).'</label>';
            if (!empty($this->description))
                echo '<span id="'.esc_attr($description_id).'" class="description customize-control-description">'.$this->description.'</span>';
            echo '<select id="'.esc_attr($input_id).'" '.$describedby_attr.$link_attr.'>';
            foreach ($choices as $value => $label) {
                echo '<option value="'.esc_attr($value).'" '.selected($val, $value, false).'>'.$label.'</option>';
            }
            echo '</select>';
        }
    }
    
    class Customize_Alpha_Color_Control extends WP_Customize_Control {
        public $type = 'alpha-color';
        public $palette;
        public $show_opacity;
        public function enqueue() {
            wp_enqueue_style( 'wp-color-picker' );
            wp_enqueue_script( 'alpha-color-picker', get_template_directory_uri() . '/assets/js/customizer_acp.js', array( 'jquery', 'wp-color-picker' ), '1.0.0', true );
        }
        public function render_content() {
            // Process the palette
            if ( is_array( $this->palette ) ) {
                $palette = implode( '|', $this->palette );
            } else {
                // Default to true.
                $palette = ( false === $this->palette || 'false' === $this->palette ) ? 'false' : 'true';
            }
            // Support passing show_opacity as string or boolean. Default to true.
            $show_opacity = ( false === $this->show_opacity || 'false' === $this->show_opacity ) ? 'false' : 'true';
            // show log for colorconcept 2.0
            $show_log = false;
            if ($this->id == 'color11' || $this->id == 'color12' || $this->id == 'color13' ||
                $this->id == 'color21' || $this->id == 'color22' || $this->id == 'color23' ||
                $this->id == 'color31' || $this->id == 'color32' || $this->id == 'color33' ||
                $this->id == 'color41' || $this->id == 'color42' || $this->id == 'color43' ||
                $this->id == 'color51' || $this->id == 'color52' || $this->id == 'color53' ||
                $this->id == 'color61' || $this->id == 'color62' || $this->id == 'color63') $show_log = true;

            // original label and description
            if (!empty($this->label))
                echo '<label class="customize-control-title">'.esc_html($this->label).'</label>';
            if (!empty($this->description))
                echo '<span class="description customize-control-description">'.$this->description.'</span>';
            // color picker
            echo '<div class="customize-control-content">
                    <input class="alpha-color-control" type="text" 
                            data-show-opacity="'.$show_opacity.'" 
                            data-palette="'.esc_attr( $palette ).'" 
                            data-default-color="'.esc_attr( $this->settings['default']->default ).'" 
                            '.$this->get_link().' />
                </div>';
            if ($show_log)
                echo '<span class="customize-control-log"></span>';
        }
    }
    class Customize_Colselect_Control extends WP_Customize_Control {
        public $type = 'colselect';
        public function render_content() {
            $input_id = '_customize-input-'.$this->id;
            $description_id = '_customize-description-'.$this->id;
            $describedby_attr = (!empty($this->description)) ? 'aria-describedby="'.esc_attr($description_id).'" ' : '';
            $link_attr = $this->get_link();

            // get all color choices
            $choices = customize_helper::get_colors();
            $val = $this->value();

            // original label and description
            if (!empty($this->label))
                echo '<label for="'.esc_attr($input_id).'" class="customize-control-title">'.esc_html($this->label).'</label>';
            if (!empty($this->description))
                echo '<span id="'.esc_attr($description_id).'" class="description customize-control-description">'.$this->description.'</span>';
            // original select
            echo '<select id="'.esc_attr($input_id).'" class="customize-control-colorselect" style="display:none" '.$describedby_attr.$link_attr.'>';
            foreach ($choices as $value => $label) {
                echo '<option value="'.esc_attr($value).'" '.selected($val, $value, false).'>'.$label['title'].'</option>';
            }
            echo '</select>';

            // custom color choice
            echo customize_helper::render_colors_control($val, $choices);
        }
    }

    class Customize_shadow_Control extends WP_Customize_Control {
        public $type = 'shadow';
        public function render_content() {
            $input_id = '_customize-input-'.$this->id;
            $description_id = '_customize-description-'.$this->id;
            $describedby_attr = (!empty($this->description)) ? 'aria-describedby="'.esc_attr($description_id).'" ' : '';
            $link_attr = $this->get_link();
            // get value
            $value = $this->value();
            // $val = array( 'type' => '', 'x' => 0, 'y' => 0, 'blur' => 0, 'spread' => 0, 'color' => 'color61', 'opacity' => 100 );
            $val = array( 'type' => '', 'x' => 0, 'y' => 0, 'blur' => 0, 'spread' => 0, 'color' => 'color31', 'opacity' => 25 );
            $colors = customize_helper::get_colors();
            if ($value != 'none') {
                $tmp = explode(" ", str_replace('+', ' ', $value));
                if ((strpos($value, 'color') > -1 && count($tmp) == 7) ||
                    (strpos($value, 'color') === false && count($tmp) == 6)) {
                    $val['type'] = $tmp[0];
                    array_splice($tmp, 0, 1);
                }
                $val['x'] = str_replace('px', '', $tmp[0]);
                $val['y'] = str_replace('px', '', $tmp[1]);
                $val['blur'] = str_replace('px', '', $tmp[2]);
                $val['spread'] = str_replace('px', '', $tmp[3]);
                if (strpos($value, 'color') > -1) {
                    $val['color'] = $tmp[4];
                    $val['opacity'] = $tmp[5];
                }
                else {
                    $color = \vc\helper::rgb2RGB($tmp[4]);
                    $val['color'] = customize_helper::get_color_from_rgb($colors, $color, $val['color']);
                    $val['opacity'] = $color['a']*100;
                }
            }

            // label and description
            if (!empty($this->label))
                echo '<label for="'.esc_attr($input_id).'" class="customize-control-title">'.esc_html($this->label).'</label>';
            if (!empty($this->description))
                echo '<span id="'.esc_attr($description_id).'" class="description customize-control-description" style="margin-bottom:10px;">'.$this->description.'</span>';
            // actual value
            echo "<input type='hidden' id='".esc_attr($input_id)."' ".$describedby_attr.$link_attr." value='".$value."' />";
                
            // custom controls
            echo '<div class="input-sdw-wrapper">';
                // x
                $lbl = __('Horizontal:', 'core');
                echo '<div style="display: inline-block; width: 45%;margin-right:10%">
                        <span class="description customize-control-description cs-range-value" data-lbl="'.$lbl.'" data-unit="px">'.$lbl.' '.$val['x'].'px</span>
                        <input type="range" style="" id="input-sdw-x-'.$this->id.'" value="'.$val['x'].'" min="-25" max="25" step="1" />
                    </div>';
                // y
                $lbl = __('Vertikal:', 'core');
                echo '<div style="display: inline-block; width: 45%">
                        <span class="description customize-control-description cs-range-value" data-lbl="'.$lbl.'" data-unit="px">'.$lbl.' '.$val['y'].'px</span>
                        <input type="range" style="" id="input-sdw-y-'.$this->id.'" value="'.$val['y'].'" min="-25" max="25" step="1" />
                    </div>';
                // blur
                $lbl = __('Verwischen:', 'core');
                echo '<div style="display: inline-block; width: 45%;margin-right:10%">
                        <span class="description customize-control-description cs-range-value" data-lbl="'.$lbl.'" data-unit="px">'.$lbl.' '.$val['blur'].'px</span>
                        <input type="range" style="" id="input-sdw-blur-'.$this->id.'" value="'.$val['blur'].'" min="0" max="50" step="1" />
                    </div>';
                // spread
                $lbl = __('Ausdehnen:', 'core');
                echo '<div style="display: inline-block; width: 45%">
                        <span class="description customize-control-description cs-range-value" data-lbl="'.$lbl.'" data-unit="px">'.$lbl.' '.$val['spread'].'px</span>
                        <input type="range" id="input-sdw-spread-'.$this->id.'" value="'.$val['spread'].'" min="-25" max="25" step="1" />
                    </div>';
            echo '</div>';
            // color
            echo '<span class="description customize-control-description" style="margin-top:10px;">'.__('Farbe', 'core').'</span>';
            echo '<select id="input-sdw-color-'.$this->id.'" class="customize-control-colorselect" style="display:none">'; // hidden color select
            foreach ($colors as $k => $v)
                echo '<option value="'.esc_attr($k).'" '.selected($val['color'], $k, false).'>'.$v['title'].'</option>';
            echo '</select>';
            echo customize_helper::render_colors_control($val['color'], $colors);
            
            echo '<div style="margin-top:10px;">';
                // type
                $lbl = __('Deckkraft:', 'core');
                echo '<div style="display: inline-block; width: 45%;margin-right:10%;vertical-align:top;">
                        <span class="description customize-control-description cs-range-value" data-lbl="'.$lbl.'" data-unit="%">'.$lbl.' '.$val['opacity'].'%</span>
                        <input type="range" class="opacity" style="width:100%" id="input-sdw-opacity-'.$this->id.'" value="'.$val['opacity'].'" min="0" max="100" step="1" />
                    </div>';
                // opacity
                echo '<div style="display: inline-block; width: 45%;">
                        <span class="description customize-control-description">'.__('Position', 'core').'</span>
                        <select id="input-sdw-type-'.$this->id.'">
                            <option value="">'._x('außen', 'small', 'core').'</option>
                            <option value="inset" '.selected($val['type'], "inset", false).'>'._x('innen', 'small', 'core').'</option>
                        </select>
                    </div>';
            echo '</div>';

        }

    }

    class Customize_preset_Control extends WP_Customize_Control {
        public $type = 'preset';
        public function render_content() {
            
            // attributes
            $input_id           = '_customize-input-'.$this->id;
            $description_id     = '_customize-description-'.$this->id;
            $describedby_attr   = (!empty($this->description)) ? 'aria-describedby="'.esc_attr($description_id).'" ' : '';
            $link_attr          = $this->get_link();
            $val                = $this->value();
            $choices            = $this->choices;
            
            // Vars
            $selected_option    = "";
            $img_url            = get_template_directory_uri()."/assets/icon/preset-picker/";
            $custom_img         = 'custom.svg';
            
            // set default custom option
            $custom_option = [
                "label" => "individuell",
                'img'   => $custom_img
            ];
            if ( isset($choices['custom']) ) {
                if (is_array($choices['custom'])) {
                    $custom_option['label'] = isset($choices['custom']['label']) ? esc_attr($choices['custom']['label']) : $custom_option['label'];
                    $custom_option['img']   = isset($choices['custom']['img'])   ? esc_attr($choices['custom']['img'])   : $custom_option['img'];
                } else {
                    $custom_option['label'] = esc_attr($choices['custom']);
                }
            }
            $choices['custom'] = $custom_option;
            
            // label and description
            if (!empty($this->label))
                echo '<label for="'.esc_attr($input_id).'" class="customize-control-title">'.esc_html($this->label).'</label>';
            if (!empty($this->description))
                echo '<span id="'.esc_attr($description_id).'" class="description customize-control-description">'.$this->description.'</span>';
            
            // render picker
            echo "<div class='preset-picker'>";
            
                // select
                echo '<select id="'.esc_attr($input_id).'" '.$describedby_attr.$link_attr.' class="preset-select">';
                foreach ($choices as $value => $option) {
                    if ($selected_option === "" || $val == $value) $selected_option = $option;
                    if (is_array($option)){
                        $label  = isset($option["label"]) ? esc_attr($option["label"]) : "";
                        $mods   = isset($option["mods"]) ? "data-mods='".json_encode($option["mods"])."'" : "";
                    } else {
                        $label  = esc_attr($option);
                        $mods   = "";
                    }

                    echo "<option value='".esc_attr($value)."' ".selected($val, $value, false)." $mods>$label</option>";
                }
                echo '</select>';
            
                // custom select
                echo "<div class='selected_option ".($custom = $val === 'custom' ? 'custom' : '')."' data-custom='".$choices['custom']['label']."'>";
                    $img    = isset($selected_option["img"]) ? esc_attr($selected_option["img"]) : $custom_img;
                    $label  = isset($selected_option["label"]) ? esc_attr($selected_option["label"]) : "";
                    if ($label === "") $label  = $selected_option !== "" ? esc_attr($selected_option) : $choices['custom']['label'];
                    echo "<div class='option'><span class='img' style='background-image: url(\"".$img_url.$img."\");'></span><span class='txt'>$label</span></div>";
                echo "</div>";
            
                // custom options
                echo "<div class='options'>";
                    foreach ($choices as $value => $option) {
                        if ($value === 'custom') continue; // don't redner custom option
                        if (is_array($option)){
                            $img    = isset($option["img"]) ? esc_attr($option["img"]) : $custom_img;
                            $label  = isset($option["label"]) ? esc_attr($option["label"]) : "";
                        } else {
                            $label  = esc_attr($option);
                            $img    = $custom_img;
                        }
                        echo "<div class='option ".($selected = $val == $value ? 'selected' : '')."' data-value='".esc_attr($value)."'><span class='img' style='background-image: url(\"".$img_url.$img."\");'></span><span class='txt'>$label</span></div>";
                    }
                echo "</div>";
            echo "</div>";
            
            
            // info box
            foreach ((array) $this->input_attrs as $styling => $text) {
                echo \vc\helper::render_info_box(['styling' => $styling, 'text' => $text]);
            }
            
        }
    }
    
    class customize_helper {
        // get all color choices
        public static $choices = array();
        public static function get_colors() {
            if (count(self::$choices) == 0)
                for ($i=1; $i<=6; $i++) {
                    for ($j=1; $j<=3; $j++) {
                        $col = 'color'.$i.$j;
                        $color = get_theme_mod($col, '');
                        self::$choices[$col] = array( 
                            'title' => __( processor::$root['--'.$col]['description'], 'core' ).' - '.$color, 
                            'color' => $color 
                        );
                    }
                }
            return self::$choices;
        }
        // get color 2.0 from rgb color
        public static function get_color_from_rgb($colors, $color, $default) {
            $new_color = $default;
            foreach ($colors as $k => $v) {
                $c = $v['color'];
                if (\vc\helper::isHex($c)) $c = \vc\helper::hex2RGB($c);
                else $c = \vc\helper::rgb2RGB($c);
                if ($color['r'] == $c['r'] && $color['g'] == $c['g'] && $color['b'] == $c['b']) {
                    $new_color = $k;
                    break;
                }
            }
            return $new_color;
        }
        // render colors control
        public static function render_colors_control($val, $choices) {
            $found = false;
            $control = "";

            $control .= '<div class="customize-control-colors"><div class="color_wrapper">';
            for ($i=1; $i<=3; $i++) {
                for ($j=1; $j<=3; $j++) {
                    $col = 'color'.$i.$j;
                    $sel = ($val == $col) ? 'selected' : '';
                    if ($val == $col) $found = true;
                    $control .= '<div class="col '.$col.' '.$sel.'" data-value="'.$col.'">
                                    <span class="col_bg"></span>
                                    <span class="col_color" style="background:'.$choices[$col]['color'].';" title="'.$choices[$col]['title'].'"></span>
                                </div>';
                }
                if ($i<3) $control .= '<div class="customize-control-colorssep"></div>';
            }
            $control .= '</div></div>';

            $display_more = "block";
            $display_cols = "none";
            $display_less = "none";
            if (!$found) {
                $display_more = "none";
                $display_cols = "inline-block";
                $display_less = "block";
            }
            $control .= '<div>';
                $control .= '<span style="display:'.$display_more.'" class="customize-control-colors-more more">'.__('mehr Farben', 'core').' ▾</span>';
            
                $control .= '<div style="display:'.$display_cols.'" class="customize-control-colors"><div class="color_wrapper">';
                $control .= '<div class="customize-control-colorssep"></div>';
                for ($i=4; $i<=6; $i++) {
                    for ($j=1; $j<=3; $j++) {
                        $col = 'color'.$i.$j;
                        $control .= '<div class="col '.$col.' '.(($val == $col) ? 'selected' : '').'" data-value="'.$col.'">
                                        <span class="col_bg"></span>
                                        <span class="col_color" style="background:'.$choices[$col]['color'].';" title="'.$choices[$col]['title'].'"></span>
                                    </div>';
                    }
                    if ($i<6) $control .= '<div class="customize-control-colorssep"></div>';
                }
                $control .= '</div></div>';
                
                $control .= '<span style="display:'.$display_less.'" class="customize-control-colors-more less">'.__('weniger', 'core').' ▴</span>';
            $control .= '</div>';

            return $control;
        }
    }

}

