(function($){
    "use strict";

    $.pixeColorSettings = {

        isChanged: false,

        // initiate content
        init: function(settings){
            if( !pixeData.colorPreset ){ return; }

            settings = $.extend({
            }, settings);
            
            var t = this;
            t.isChanged = false;

            var container = $('<div class="pixe-color-settings pixe-box-sizing" ></div>');
            var tab = $('<div class="pixe-settings-tab" ></div>');
            tab.appendTo(container);

            // init header area
            t.tabHead = $('<div class="pixe-settings-tab-head" ></div>');
            t.tabHead.append(pixei18n.preset.color);
            tab.append(t.tabHead);
            
            // init content area
            t.tabContent = $('<div class="pixe-settings-tab-content" ></div>');
            tab.append(t.tabContent);
            t.getPresetTab(t.tabContent, pixeData.colorPreset['active-preset']);

            // popup
            if( settings.container ){
                settings.container.append(container);
            }else{
                var lb = new $.pixeLightboxPopup({
                    class: 'pixe-lb-color-settings',
                    content: container,
                    onClose: function(){
                        if( !t.isChanged ) return; 

                        // sync variable with iframe
                        if( $.pixeBuilder ){
                            $.pixeBuilder.setIframeData(['colorPreset']);
                        }
                    }
                });
                
                t.tabHead.append($.pixeGetAdminIcon('cancel', { class: 'pixe-close' }));
                t.tabHead.on('click', '.pixe-close', function(){
                    lb.close();
                });
            }

        },

        getPresetTab: function(tabContent, activePreset = ''){
            function getTitle(slug, title = '', active = false){
                var html  = '<div class="' + (active? 'pixe-active': '') + '" data-preset-id="' + slug + '" >';
                    html += '<span class="pixe-text" >' + title + '</span>';
                    html += $.pixeGetAdminIcon('check', { class: 'pixe-set-live' });
                    html += '</div>';
                return html;
            }
            function getCustomTitle(slug, title = '', active = false){
                var html  = '<div class="' + (active? 'pixe-active': '') + '" data-preset-id="' + slug + '" >';
                    html += '<span class="pixe-text" >' + title + '</span>';
                    html += $.pixeGetAdminIcon('check', { class: 'pixe-set-live' });
                    html += '</div>';
                return html;
            }
            
            var t = this;
            t.activePreset = activePreset;

            // init area
            var container = $('<div class="pixe-color-preset-settings" ></div>');
            tabContent.empty();
            tabContent.append(container);
            
            var presetWrap = $('<div class="pixe-color-preset-option" ></div>');
            var preset = $('<div class="pixe-content pixe-scrollbar"></div>');
            container.append(presetWrap.append(preset));
            
            // 2 loop for core & custom preset
            for( var i = 0; i <= pixeData.colorPreset.presetOrder.length; i++ ){
                var slug = pixeData.colorPreset.presetOrder[i];
                if( t.activePreset == '' ){
                    t.activePreset = slug;
                }
                
                if( pixeData.colorPreset.preset[slug] && pixeData.colorPreset.preset[slug].core ){
                    var isActive = (t.activePreset == slug);
                    preset.append(getTitle(slug, pixeData.colorPreset.preset[slug].label, isActive));
                }
            }
            preset.append('<div class="pixe-divider" ></div>');
            for( var i = 0; i <= pixeData.colorPreset.presetOrder.length; i++ ){
                var slug = pixeData.colorPreset.presetOrder[i];
                if( pixeData.colorPreset.preset[slug] && !pixeData.colorPreset.preset[slug].core ){
                    var isActive = (t.activePreset == slug);
                    preset.append(getCustomTitle(slug, pixeData.colorPreset.preset[slug].label, isActive));
                }
            }

            // preset content
            var presetContent = $('<div class="pixe-color-preset-content pixe-scrollbar" ></div>');
            container.append(presetContent);
            t.getPresetContent(presetContent, t.activePreset);

            // edit another preset
            preset.on('click', '[data-preset-id]', function(){
                if( $(this).hasClass('pixe-active') ) return;
                $(this).addClass('pixe-active').siblings().removeClass('pixe-active');

                t.activePreset = $(this).attr('data-preset-id');
                t.getPresetContent(presetContent, t.activePreset);
            });
            t.bindPresetHeaderEvents(presetContent, preset, getCustomTitle);

            // add new preset
            var addNew = $('<div class="pixe-preset-new" ></div>');
            var html  = '<label>' + pixei18n.preset.newPreset + '</label>';
                html += '<div class="pixe-input" ><input type="text" data-field="name" placeholder="Type Variable name..." /></div>';
                html += '<div class="pixe-ss-button" >Create Preset</div>';
            container.append(addNew.append(html));

            function createPreset(input){
                var name = input.val().trim();
                
                // invalid name
                if( name.length == 0 || !$.pixeIsNameValid(name) ){
                    $.pixeConfirmationBox({
                        title: 'Invalid Name',
                        message: 'Please use only English characters, number or space in your preset name.',
                        cancelText: ''
                    });
                    return;
                }

                var slug = $.pixeToSlug(name);
                if( !pixeData.colorPreset.preset[slug] ){

                    // add data
                    pixeData.colorPreset.preset[slug] = { label: name, value: {} };
                    pixeData.colorPreset.presetOrder.push(slug);
                    
                    // add item
                    var item = $(getCustomTitle(slug, name));
                    preset.append(item);
                    item.trigger('click');

                    input.val('');
                    t.updateData();
                }else{
                    $.pixeConfirmationBox({
                        title: 'Preset Already Existed',
                        message: 'Please fill another name to create new preset.',
                        cancelText: ''
                    });
                    return;
                }
            }

            // add new event
            addNew.on('click', '.pixe-ss-button', function(){
                createPreset(addNew.find('input[type="text"]'));
            });
            addNew.on('keydown', 'input[type="text"]', function(e){
                if( e.key != 'Enter' && e.which != 13 ) return;
                e.preventDefault();
                createPreset($(this));
            });

            // set live preset
            preset.find('[data-preset-id="' + pixeData.colorPreset['active-preset'] + '"]').addClass('pixe-live');
            preset.on('click', '.pixe-set-live', function(){
                var item = $(this).closest('[data-preset-id]');
                item.addClass('pixe-live').siblings().removeClass('pixe-live');

                pixeData.colorPreset['active-preset'] = item.attr('data-preset-id');
                t.getPresetContent(presetContent, t.activePreset);
                t.updateData();
            });

        },

        getPresetTitle: function(slug){
            if( pixeData.colorPreset.preset[slug] && pixeData.colorPreset.preset[slug].label ){
                return pixeData.colorPreset.preset[slug].label;
            }

            return slug;
        },

        getNextPresetSlug: function(slug){
            var baseSlug = slug || 'preset';
            var newSlug = baseSlug;
            var index = 2;

            while( pixeData.colorPreset.preset[newSlug] ){
                newSlug = baseSlug + '-' + index;
                index++;
            }

            return newSlug;
        },

        getPresetHeader: function(activePreset){
            var presetData = pixeData.colorPreset.preset[activePreset] || {};
            var presetTitle = this.getPresetTitle(activePreset);
            var canEdit = !presetData.core && activePreset != pixeData.colorPreset['active-preset'];
            var html  = '<div class="pixe-preset-item-header" >';
                html += '<label>Preset</label>';
                html += '<div class="pixe-actions" >';
                html += $.pixeGetAdminIcon('copy', {class: 'pixe-copy'});
                if( canEdit ){
                    html += $.pixeGetAdminIcon('edit', {class: 'pixe-edit'});
                    html += $.pixeGetAdminIcon('check', {class: 'pixe-submit pixe-with-bg pixe-hidden'});
                    html += $.pixeGetAdminIcon('cancel', {class: 'pixe-cancel pixe-with-bg pixe-hidden'});
                    html += $.pixeGetAdminIcon('remove', {class: 'pixe-remove'});
                }
                html += '</div>';
                html += '<div class="pixe-name" >';
                html += '<span>' + $.pixeEscHtml(presetTitle) + '</span>';
                if( canEdit ){
                    html += '<div class="pixe-input" style="display: none;" ><input type="text" data-field="name" value="' + $.pixeEscAttr(presetTitle) + '" /></div>';
                }
                html += '</div>';
                html += '</div>';

            return html;
        },

        bindPresetHeaderEvents: function(presetContent, preset, getCustomTitle){
            var t = this;

            // copy active preset
            presetContent.on('click', '.pixe-preset-item-header .pixe-copy', function(){
                var oldSlug = t.activePreset;
                var newSlug = t.getNextPresetSlug(oldSlug);
                var newTitle = t.getPresetTitle(oldSlug) + ' Copy';
                var newData = $.pixeClone(pixeData.colorPreset.preset[oldSlug]);

                newData.label = newTitle;
                delete newData.core;

                pixeData.colorPreset.preset[newSlug] = newData;
                pixeData.colorPreset.presetOrder.push(newSlug);

                var item = $(getCustomTitle(newSlug, newTitle));
                preset.append(item);
                item.trigger('click');

                t.updateData();
            });

            // edit preset name
            presetContent.on('click', '.pixe-preset-item-header .pixe-edit', function(){
                var header = presetContent.find('.pixe-preset-item-header');

                header.find('.pixe-copy, .pixe-edit, .pixe-remove').addClass('pixe-hidden');
                header.find('.pixe-submit, .pixe-cancel').removeClass('pixe-hidden');
                header.find('.pixe-name span').hide();
                header.find('.pixe-input').show();
                header.find('[data-field="name"]').focus().select();
            });

            // cancel preset name edit
            presetContent.on('click', '.pixe-preset-item-header .pixe-cancel', function(){
                t.getPresetContent(presetContent, t.activePreset);
            });

            // change preset name
            presetContent.on('click', '.pixe-preset-item-header .pixe-submit', function(){
                var input = presetContent.find('[data-field="name"]');
                var name = input.val().trim();

                if( name.length == 0 || !$.pixeIsNameValid(name) ){
                    $.pixeConfirmationBox({
                        title: 'Invalid Name',
                        message: 'Please use only English characters, number or space in your preset name.',
                        cancelText: ''
                    });
                    return;
                }

                pixeData.colorPreset.preset[t.activePreset].label = name;
                preset.find('[data-preset-id="' + t.activePreset + '"] .pixe-text').html(name);
                t.getPresetContent(presetContent, t.activePreset);
                t.updateData();
            });

            // submit/cancel preset name edits with keyboard
            presetContent.on('keydown', '[data-field="name"]', function(e){
                if( e.key == 'Enter' ){
                    presetContent.find('.pixe-preset-item-header .pixe-submit').trigger('click');
                }

                if( e.key == 'Escape' ){
                    t.getPresetContent(presetContent, t.activePreset);
                }
            });

            // remove active preset
            presetContent.on('click', '.pixe-preset-item-header .pixe-remove', function(){
                var currentPreset = t.activePreset;
                var currentPresetItem = preset.find('[data-preset-id="' + currentPreset + '"]');

                $.pixeConfirmationBox({
                    title: 'Remove Custom Preset',
                    message: 'You are about to remove a custom preset. Please note that this process cannot be undone.',
                    onSuccess: function(){

                        // delete preset data
                        var index = pixeData.colorPreset.presetOrder.indexOf(currentPreset);
                        if( index >= 0 ){ pixeData.colorPreset.presetOrder.splice(index, 1); }
                        delete pixeData.colorPreset.preset[currentPreset];

                        // remove object
                        currentPresetItem.slideUp(150, function(){
                            $(this).remove();
                        });

                        t.updateData();

                        // switch preset
                        preset.find('[data-preset-id]').first().trigger('click');
                    }
                });
            });
        },

        getPresetContent: function(presetContent, activePreset){
            var t = this;
            var presetData = pixeData.colorPreset.preset[activePreset];
            var presetValue = presetData.value? presetData.value: {};
            presetContent.empty();

            // preset header
            presetContent.append(t.getPresetHeader(activePreset));

            var form = $('<div class="pixe-form pixe-clearfix" ></div>');
            form.appendTo(presetContent);

            // update color data
            function updatePresetColor(){
                delete presetData.value;
                delete presetData.customColorOrder;
                
                form.find('[data-slug]').each(function(){
                    if( $(this).data('value') ){
                        if( !presetData.value ){ presetData.value = {}; }
                        presetData.value[$(this).attr('data-slug')] = $(this).data('value');
                    }
                    if( $(this).hasClass('pixe-custom') ){
                        if( !presetData.customColorOrder ){ presetData.customColorOrder = []; }
                        presetData.customColorOrder.push($(this).attr('data-slug'));
                    }
                });
                t.updateData();
            }
            
            // system color
            form.append('<div class="pixe-title" >System Colors</div>');
            for( var slug in $.pixeColorStyle.systemColor ){
                form.append(t.getPresetColorItem(slug, $.pixeColorStyle.systemColor[slug], presetValue[slug], true));
            }

            // custom color
            form.append('<div class="pixe-title" >Custom Colors</div>');
            if( presetData.customColorOrder ){
                for( var i in presetData.customColorOrder ){
                    var slug = presetData.customColorOrder[i];
                    form.append(t.getPresetColorItem(slug, presetData.customColor[slug], presetValue[slug], false));
                }
            }

            // bind colorpicker
            form.on('click', '.pixe-color-preset-item', function(e){
                if( $(e.target).closest('.pixe-action').length ) return;

                var isClosed = false;
                var isChanged = false;
                var presetItem = $(this);
                var colorDisplay = $(this).find('.pixe-color-display');

                new $.pixeStyleSelector({
                    target: $(this),
                    type: 'edit-color-variable',
                    obj: {'': {color: presetItem.data('value')}},
                    onChange: function(value){
                        var color = $.pixeGetColor(value.color);
                        if( color.css ){
                            presetItem.data('value', value.color);
                            colorDisplay.css('background', color.css);
                        }else{
                            presetItem.removeData('value');
                            colorDisplay.css('background', '');
                        }
                        
                        isChanged = true;
                        if( isClosed ){ updatePresetColor(); }
                    },
                    onClose: function(){
                        if( isChanged ){ updatePresetColor(); }
                        isClosed = true;
                    }
                });
            });

            // bind reordering
            form.sortable({
                items: '.pixe-custom',
                update: function(){
                    updatePresetColor();
                }
            });

            // add new custom color
            var addNew = $('<div class="pixe-preset-subitem-new" >' + $.pixeGetAdminIcon('plus') + 'Add Color</div>');
            form.append(addNew);

            // new color
            addNew.on('click', function(){
                t.newPresetColor(addNew, activePreset);
            });

            // remove custom color
            form.on('click', '.pixe-remove', function(){
                var item = $(this).closest('.pixe-color-preset-item');
                var slug = item.attr('data-slug');

                $.pixeConfirmationBox({
                    title: 'Remove Custom Color',
                    message: 'You are about to remove a custom color. Please note that this process cannot be undone.',
                    onSuccess: function(){
                        item.slideUp(150, function(){ $(this).remove(); });
        
                        delete presetData.value[slug];
                        delete presetData.customColor[slug];
                        
                        var order = presetData.customColorOrder.indexOf(slug)
                        if( order >= 0 ){
                            presetData.customColorOrder.splice(order, 1);
                        }
                        if( presetData.customColorOrder.length == 0 ){
                            delete presetData.customColorOrder;
                        }
                        
                        t.updateData();
                    }
                });
                
            });

            // edit custom color
            form.pixeInlineTextEdit({
                onValidate: function(name){
                    if( name.length == 0 || !$.pixeIsNameValid(name) ){
                        $.pixeConfirmationBox({
                            title: 'Invalid Name',
                            message: 'Please use only English characters, number or space in your name.',
                            cancelText: ''
                        });
                        return false;
                    }
                    return true;
                },
                onSave: function(item, name){
                    var slug = item.attr('data-slug');
                    presetData.customColor[slug] = name;
                    t.updateData();
                }
            });
        },

        // preset color item
        getPresetColorItem: function(slug, label, value, system = true){
            var item  = $('<div class="pixe-color-preset-item pixe-inline-text-edit" ></div>');
            item.attr('data-slug', slug);
            item.data('value', value);
            item.append('<div class="pixe-color-display" ></div>');
            item.append('<span class="pixe-text" >' + label + '</span>');

            if( value ){
                var color = $.pixeGetColor(value);
                if( color.css ){
                    item.find('.pixe-color-display').css('background', color.css);
                }
            }
            
            if( !system ){
                item.addClass('pixe-custom');

                var action  = $.pixeGetAdminIcon('edit', {class: 'pixe-edit pixe-action'});
                    action += $.pixeGetAdminIcon('remove', {class: 'pixe-remove pixe-action'});
                    action += $.pixeGetAdminIcon('check', {class: 'pixe-save pixe-action'});
                item.append(action);
            }

            return item;
        },

        // add new color
        newPresetColor: function(formButton, activePreset){
            var t = this;
            var confirmBox = $.pixeColorStyle.getNewColorPopup();
            
            // create new action
            confirmBox.on('click', '.pixe-submit', function(){

                var presetData = pixeData.colorPreset.preset[activePreset];
                var input = confirmBox.find('input[type="text"]');
                var name = input.val().trim();
                var slug = $.pixeToSlug(name);

                if( !$.pixeColorStyle.testColorName(presetData, name, slug) ) return;
                
                // ensure if object is created
                if( !presetData.customColor ){
                    presetData.customColor = {};
                }
                if( !presetData.customColorOrder ){
                    presetData.customColorOrder = [];
                }

                // add data 
                presetData.customColor[slug] = name;
                presetData.customColorOrder.push(slug);

                // add new colorpicker to color preset area
                if( formButton ){
                    var colorItem = t.getPresetColorItem(slug, name, presetData.value[slug], false);
                    colorItem.insertBefore(formButton);
                }
                
                // close
                confirmBox.fadeOut(150, function(){
                    $(this).remove();
                });

                // update data
                t.updateData();
            });

        },

        updateData: function(){
            var t = this;
            t.isChanged = true;

            // update builder color style
            $.pixeColorStyle.updateStyle();

            // set preset style
            $.pixeColorStyle.setPresetStyle();
            
            if( $.pixeBuilder ){
                $.pixeUpdateCombobox($.pixeBuilder.settingsPanel.panel, {
                    selector: '.pixe-color-preset-combobox',
                    options: 'colorPreset'
                });
            }
            
            // save data
            var ajaxData = $.pixeGetAjaxData({
                action: 'pixe_save_colors',
                colors: pixeData.colorPreset,
                site: pixeData.site
            });

            $.pixeAjax({
                ajaxData: ajaxData,
                onSuccess: function(data){
                    if( $.pixeDebug ){ console.log('color settings updated: ', data); }
                }
            });

        },
    }

})(jQuery);	
