/**
 * @version    $Id$
 * @package    VS PageBuilder
 * @author     InnoGears Team <support@www.innogears.com>
 * @copyright  Copyright (C) 2012 www.innogears.com. All Rights Reserved.
 * @license    GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
 *
 * Websites: http://www.www.innogears.com
 * Technical Support:  Feedback - http://www.www.innogears.com
 */


/**
 * Root wrapper div #form-container, contains all content
 * Columns are seperated by a 12px seperators
 * HTML structure: #form-container [.jsn-row-container [.jsn-column-container]+]+
 *
 */

(function ($) {
    function JSNLayoutCustomizer() {

    }

    JSNLayoutCustomizer.prototype = {
        init:function (_this) {
            // Get necessary elements
            this.wrapper = $("#form-container");
            this.wrapper_width = 0;
            this.columns = $(_this).find('.jsn-column-container');
            this.addcolumns = '.add-container';
            this.addelements = '.vs-more-element';
            this.resizecolumns = '.ui-resizable-e';
            this.deletebtn = '.item-delete';
            this.moveItemEl = "[class^='jsn-move-']";
            this.resize = 1;
            this.effect = 'easeOutCubic';
            this.padding = 5;   
            // Initialize variables
            this.maxWidth = $('#form-container').width();
            // do this to prevent columns drop
            $('#form-container').css('width', (this.maxWidth - this.padding * 2) + 'px');
            this.spacing = 12;
            var self	= this;

            // Sortable for columns in row
            $(_this).find(".vs-row-content").livequery(function(){
                $(this).sortable({
                    axis:'x',
                    //   placeholder:'ui-state-highlight',
                    start:$.proxy(function (event, ui) {
                        ui.placeholder.append(ui.item.children().clone());
                        $(ui.item).parents(".vs-row-content").find(".ui-resizable-handle").hide();
                    }, this),
                    handle:".jsn-handle-drag",
                    stop:$.proxy(function (event, ui) {
                        $(ui.item).parents(".vs-row-content").find(".ui-resizable-handle").show();
                        self.wrapper.trigger('vs-pagebuilder-layout-changed', [ui.item]);
                    }, this)
                });
            });
            $(_this).find(".vs-row-content").disableSelection();

            // has not inited before, so call all functions
            this.addRow(this, this.wrapper);
            this.addNestedRow(this, this.wrapper);
            //this.updateSpanWidthPBDL(this, this.wrapper, this.maxWidth);
            this.initResizable(-1);
            this.addColumn($("#tmpl-vs_column").html());
            this.removeItem();
            this.moveItem();
            this.moveItemDisable(this.wrapper);
            this.resizeHandle(this);
            this.sortableElement();
            this.addElement();
            this.showAddLayoutBox();
            this.showSaveLayoutBox();
            this.searchElement();    
            this.updateSpanWidthPBDL(this, this.wrapper, this.maxWidth);

        },

        // Update column width when window resize
        resizeHandle:function (self) {
            $(window).resize(function() {
                if($('body').children('.ui-dialog').length)
                    $('html, body').animate({scrollTop: $('body').children('.ui-dialog').first().offset().top - 60}, 'fast');
                self.fnReset(self);
                var _rows	= $('.jsn-row-container', self.wrapper);
                self.wrapper.trigger('vs-pagebuilder-column-size-changed', [_rows]);
            });
            $("#vs_page_builder").resize(function() {
                self.fnReset(self);
            });
        },

        // reset when resize window/pagebuilder
        fnReset:function(self, trigger){
            if((self.resize || trigger) && $("#form-design-content").width()){
                // do this to prevent columns drop
                $("#form-container").width(($("#form-design-content").width() - this.padding*2) + 'px');
                self.maxWidth = $("#form-container").width();
                // re-calculate step width
                self.calStepWidth(0, 'reset');
                self.initResizable(-1, false);
                self.updateSpanWidthPBDL(self, self.wrapper, self.maxWidth);
            }
        },

        // Calculate step width when resize column
        calStepWidth:function(countColumn, reset){
            var this_column = this.columns;
            if(reset != null){
                this_column = $("#form-container").find(".jsn-row-container.outer").first().find('.jsn-column-container.outer');
                //console.log('col : ' ,  this_column);
            }

            var formRowLength = (countColumn > 0) ? countColumn : this_column.length;
            this.step = parseInt((this.maxWidth - (this.spacing * (formRowLength -1))) / 12);

        },
        
        // Calculate step width when resize column for inner row
        calInnerStepWidth:function(countColumn, reset){
            var container = $("#form-container").find(".jsn-row-container.inner").first();
            var this_column = container.find('.jsn-column-container.inner')
            var maxWidth = container.width();
            var formRowLength = (countColumn > 0) ? countColumn : this_column.length;
            return step = parseInt((maxWidth - (this.spacing * (formRowLength -1))) / 12);
        },

        // Resize columns
        initResizable:function (countColumn, getStep) {
            var self = this;
            if(getStep == null || getStep)
                self.calStepWidth(countColumn);


            var handleResize = $.proxy(function (event, ui) {
                //console.log(2703, ui);     
                if(self.getLayoutType(ui.element) == '.inner'){
                    var step = self.calInnerStepWidth(0); 
                }else{
                    var step = self.step;
                }                      
                var thisWidth = ui.element.width(),
                bothWidth = ui.element[0].__next[0].originalWidth + ui.originalSize.width,
                nextWidth = bothWidth - thisWidth;

                if (thisWidth < step) {
                    thisWidth = step;
                    nextWidth = bothWidth - thisWidth;

                    // Set min width to prevent column from collapse more
                    ui.element.resizable('option', 'minWidth', step);
                } else if (nextWidth < step) {
                    nextWidth = step;
                    thisWidth = bothWidth - nextWidth;

                    // Set max width to prevent column from expand more
                    ui.element.resizable('option', 'maxWidth', thisWidth);
                }    
                var this_span = parseInt(thisWidth / step);
                var next_span = parseInt(nextWidth / step);  
                thisWidth = parseInt(parseInt(this_span)*bothWidth/(this_span + next_span));
                nextWidth = parseInt(parseInt(next_span)*bothWidth/(this_span + next_span));
                // Snap column to grid
                ui.element.css('width', thisWidth + 'px');
                // Resize next sibling element as well
                ui.element[0].__next.css('width', nextWidth + 'px');
                // show % width
                //console.log(1500,$(ui.element));
                var col_type = self.getLayoutType($(ui.element));
                //console.log(8000);
                self.percentColumn($(ui.element),"add",step);
                var _row	= $(ui.element).parents('.jsn-row-container'+col_type);
                //console.log(1278,_row);
                self.wrapper.trigger('vs-pagebuilder-column-size-changed', [_row]);
            }, this);
            // Reset resizable column

            $(".jsn-column").each($.proxy(function (i, e) {
                //console.log((self.getLayoutType($(e)) == '.inner')); 
                if(self.getLayoutType($(e)) == '.inner'){
                    var step = self.calInnerStepWidth(0); 
                }else{
                    var step = self.step;
                }       
                //console.log(1025 , e , step , self.step);                  
                $(e).resizable({
                    handles:'e',
                    minWidth:step,
                    grid:[step, 0],
                    start:$.proxy(function (event, ui) {
                        ui.element[0].__next = ui.element[0].__next || ui.element.parent().next().children();
                        ui.element[0].__next[0].originalWidth = ui.element[0].__next.width();
                        ui.element.resizable('option', 'maxWidth', '');
                        // disable resize handle
                        self.resize = 0;
                    }, this),
                    resize:handleResize,
                    stop:$.proxy(function (event, ui) {   
                        
                        //console.log(800); 
  
                        //console.log(1875,ui.element);
                        var col_type = self.getLayoutType($(ui.element));
                        
                        var oldValue = parseInt(ui.element.find(".jsn-column-content"+col_type).attr("data-column-class").replace('span', '')),
                        
                        // Round up, not parsetInt
                        newValue = Math.round(ui.element.width() / step),
                        nextOldValue = parseInt(ui.element[0].__next.find(".jsn-column-content"+col_type).attr("data-column-class").replace('span', ''));
                        // Update field values
                        if (nextOldValue > 0 && newValue > 0) {
                            //console.log(3232, ui.element[0].__next.find(".jsn-column-content"+col_type));                                                 
                            //console.log(ui.element,newValue);
                            ui.element.find(".jsn-column-content"+col_type).attr("data-column-class", 'span' + newValue);
                            ui.element[0].__next.find(".jsn-column-content"+col_type).attr('data-column-class', 'span' + (nextOldValue - (newValue - oldValue)));
                            // Update visual classes
                            //console.log( ui.element[0].__next,(nextOldValue - (newValue - oldValue)));
                            ui.element.attr('class', ui.element.attr('class').replace(/\bspan\d+\b/, 'span' + newValue));
                            ui.element[0].__next.attr('class', ui.element[0].__next.attr('class').replace(/\bspan\d+\b/, 'span' + (nextOldValue - (newValue - oldValue))));
                            ui.element.find("[name^='shortcode_content']").first().text(ui.element.find("[name^='shortcode_content']").first().text().replace(/span\d+/, 'span' + newValue));
                            ui.element[0].__next.find("[name^='shortcode_content']").first().text(ui.element[0].__next.find("[name^='shortcode_content']").first().text().replace(/span\d+/, 'span' + (nextOldValue - (newValue - oldValue))));
                            $(e).css({
                                "height":"auto"
                            });
                        }
                        // enable resize handle
                        self.resize = 1;
                        self.updateSpanWidthPBDL(self, self.wrapper, $("#form-container").width());
                        //console.log(9000);
                        self.percentColumn($(ui.element),"remove",step);
                    }, this)
                });
            }, this));

            // remove duplicated resizable-handle div
            if(countColumn > 0){
                $(".jsn-column").each(function(){
                    if($(this).find('.ui-resizable-handle').length > 1){
                        //console.log($(this));
                        //$(this).find('.ui-resizable-handle').last().remove();
                    }
                        
                })
            }
        },
        toFixed:function(value, precision){
            var power = Math.pow(10, precision || 0);
            return String(Math.round(value * power) / power);
        },
        getSpan:function(this_){
            //console.log(100 , ' '  , this_);
            //console.log(this_,$(this_).find('.jsn-column-content').first(),$(this_).find('.jsn-column-content').first().attr('data-column-class'));
            return $(this_).find('.jsn-column-content').first().attr('data-column-class').replace('span', '');
        },
        getLayoutType:function(el){
            if(el.hasClass('inner')){
                return '.inner';    
            } 
            else return '.outer';
        },   
        percentColumn:function (element, action,step) {
            var self = this;
            //console.log(3 , ' ' , element);
            
            var col_type = self.getLayoutType(element);
            
            if (action == "add") {

                var this_parent = $(element).parents(".jsn-column-container"+col_type);
                
                // get current columnm & next column
                var cols = [this_parent.find('.jsn-column'+col_type), this_parent.next('.jsn-column-container'+col_type).find('.jsn-column'+col_type)];
                
                //console.log(1702 , cols);
                // count total span of this column & next column
                var spans = 0;
                $.each(cols, function () {
                    spans += parseInt(self.getSpan(this)); 
                })
                
                var parents_width = this_parent.parent().width();
                
                // show percent tooltip of this column & the next column
                var updated_spans = [];
                $.each(cols, function (i) {
                    var thisCol = this;  
                    var round = (i == cols.length - 1) ? 1 : 0;
                    
                    var parcent_width = (($(this).width() + 6) / parents_width) * 100; 
                    
                    var thisSpan = parseInt($(this).width() / step) + round;
                    //console.log(cols.length , (i == cols.length - 1) , round , $(this).width() , step , ($(this).width() / step) , parseInt($(this).width() / step) , thisSpan , parcent_width ,  parcent_width / step );
                    if(i > 0){
                        //console.log((i > 0) , thisSpan);
                        thisSpan = ((spans - updated_spans[i - 1]) < thisSpan) ? (spans - updated_spans[i - 1]) : thisSpan;   
                    }
                    updated_spans[i] = thisSpan; 
                    
                    //console.log(thisCol, col_type , thisSpan);
                    self.showPercentColumn(thisCol, col_type , thisSpan);
                });
                // show percent tooltip of other columns
                $(element).parents(".jsn-row-container"+col_type).find(".jsn-column"+col_type).each(function(){
                    
                    if(!$(this).find(".vs-pb-layout-percent-column").length){
                        var thisCol = this;
                        //console.log(466,thisCol);
                        var thisSpan = self.getSpan(this);
                        //console.log(thisCol, col_type , thisSpan , '------');
                        self.showPercentColumn(thisCol, col_type , thisSpan);
                    }
                })

            }
            if (action == "remove") {
                var container = $(element).parents(".jsn-row-container");
                $(container).find(".vs-pb-layout-percent-column").remove();
            }
        },
        // Show percent tooltip when know span of this column
        showPercentColumn:function(thisCol, col_type , thisSpan){  
            //console.log(thisCol, col_type , thisSpan);
            var maxCol = 12;
            var percent = this.toFixed(thisSpan / maxCol * 100, 2).replace(".00", "") + "%";   
            //console.log(thisCol, col_type , thisSpan , percent);
            var thumbnail = $(thisCol).find(".thumbnail" + col_type);
            $(thumbnail).css('position', 'relative');
            // $(thumbnail).find("percent-column").remove();
            if ($(thumbnail).find(".vs-pb-layout-percent-column").length) {
                $(thumbnail).find(".vs-pb-layout-percent-column .jsn-percent-inner").html(percent);
            } else {
                $(thumbnail).append(
                    $("<div/>", {"class":"jsn-percent-column vs-pb-layout-percent-column"}).append(
                        $("<div/>", {"class":"jsn-percent-arrow"})
                    ).append(
                        $("<div/>", {"class":"jsn-percent-inner"}).append(percent)
                    )
                )
            }
            var widthThumbnail = $(thumbnail).width();
            var widthPercent = $(thumbnail).find(".vs-pb-layout-percent-column").width();
            $(thumbnail).find(".vs-pb-layout-percent-column").css({"left":parseInt((widthThumbnail + 10) / 2) - parseInt(widthPercent / 2) + "px"});
            $(thumbnail).find(".vs-pb-layout-percent-column .jsn-percent-arrow").css({"left":parseInt(widthPercent / 2) - 4 + "px"});
        },

        // Add Row
        addRow:function(self, this_wrapper){
            this.wrapper.delegate('#jsn-add-container',"click",function(e) {
                    e.preventDefault();
                    if($("#form-container").find('.jsn-row-container.outer').last().is(':animated')) return;
                    // animation
                    $(this).before(vs_pb_remove_placeholder($("#tmpl-vs_row").html(), 'custom_style', 'style="display:none"'));
                    var new_el = $("#form-container").find('.jsn-row-container.outer').last();
                    var height_ = new_el.height();
                    new_el.css({'opacity' : 0, 'height' : 0});
                    new_el.addClass('overflow_hidden');
                    new_el.show();
                    new_el.animate({height: height_},300,self.effect, function(){
                        new_el.removeClass('overflow_hidden');
                        $(this).animate({opacity:1},300,self.effect,function(){
                            new_el.css('height','auto');
                        });
                    });
                    // enable/disable move icons
                    self.moveItemDisable(this_wrapper);
                    self.updateSpanWidthPBDL(self, self.wrapper, $("#form-container").width());
                });
        },        
        
        // Add Nested Row
        addNestedRow:function(self, this_wrapper){
            this.wrapper.delegate('.vs-more-innerrow',"click",function(e) {
                e.preventDefault();
                $this = $(this);
                var target = $this.parent('.add-more-action').parent('.item-container').children('.item-container-content');
                //console.log(target);
                //console.log(vs_pb_remove_placeholder($("#tmpl-vs_innerrow").html(), 'custom_style', 'style="display:none"'));
                target.append(vs_pb_remove_placeholder($("#tmpl-vs_innerrow").html(), 'custom_style', 'style="display:none"'));
                var new_el = target.find('.jsn-row-container.inner').last();
                var height_ = new_el.height();
                new_el.css({'opacity' : 0, 'height' : 0});
                new_el.addClass('overflow_hidden');
                new_el.show();
                new_el.animate({height: height_},300,self.effect, function(){
                    new_el.removeClass('overflow_hidden');
                    $(this).animate({opacity:1},300,self.effect,function(){
                        new_el.css('height','auto');
                    });
                });

                // update width for colum of this new row
                var parentForm = self.wrapper.find(".jsn-row-container.outer").last();
                self.updateSpanWidth(1, self.maxWidth, parentForm);
                self.updateSpanWidthPBDL(self, self.wrapper, $("#form-container").width());
            });
                
        },

        // Wrap content of row
        wrapContentRow:function(a,b,direction){
            var self = this;
            if(a.is(':animated') || b.is(':animated')) return;
            var this_wrapper = self.wrapper;
            var stylea = self.getBoxStyle(a);
            var styleb = self.getBoxStyle(b);
            var time = 500, extra1 = 16, extra2 = 16, effect = self.effect;
            if(direction > 0){
                a.animate({top: '-'+(styleb.height + extra1)+'px'}, time, effect, function(){});
                b.animate({top: ''+(stylea.height + extra2)+'px'}, time, effect, function(){
                    a.css('top', '0px');
                    b.css('top', '0px');
                    a.insertBefore(b);
                    self.moveItemDisable(this_wrapper);
                });
            }
            else{
                a.animate({top: ''+(styleb.height + extra2)+'px'}, time, effect, function(){});
                b.animate({top: '-'+(stylea.height + extra1)+'px'}, time, effect, function(){
                    a.css('top', '0px');
                    b.css('top', '0px');
                    a.insertAfter(b);
                    self.moveItemDisable(this_wrapper);
                });
            }
        },

        // Handle when click Up/Down Row Icons
        moveItem:function(){
            var self = this;
            this.wrapper.delegate(this.moveItemEl, "click",function(){
                if(!$(this).hasClass("disabled")){
                    var otherRow, direction;
                    var class_ = $(this).attr("class");
                    var parent = $(this).parents(".jsn-row-container.outer");
                    var parent_idx = parent.index(".jsn-row-container.outer");
                    if(class_.indexOf("jsn-move-up") >= 0){
                        otherRow = self.wrapper.find(".jsn-row-container.outer").eq(parent_idx-1);
                        direction = 1;
                    }else if(class_.indexOf("jsn-move-down") >= 0){
                        otherRow = self.wrapper.find(".jsn-row-container.outer").eq(parent_idx+1);
                        direction = -1;
                    }
                    if(otherRow.length == 0) return;
                    self.wrapContentRow(parent, otherRow, direction);
                    // Set trigger timeout to be sure it happens after animation
                    setTimeout(function (){
                    	self.wrapper.trigger('vs-pagebuilder-layout-changed', [parent]);
                    }, 1001);

                }
            });
        },

        // Disable Move Row Up, Down Icons
        moveItemDisable:function(this_wrapper){
        	var self	= this;
            this_wrapper.find(this.moveItemEl).each(function(){
                var class_ = $(this).attr("class");
                var parent = $(this).parents(".jsn-row-container.outer");
                var parent_idx = parent.index(".jsn-row-container.outer");
                // add "disabled" class
                if(class_.indexOf("jsn-move-up") >= 0){
                    if(parent_idx == 0)
                        $(this).addClass("disabled");
                    else
                        $(this).removeClass("disabled");
                }
                else if(class_.indexOf("jsn-move-down") >= 0){
                    if(parent_idx == this_wrapper.find(".jsn-row-container.outer").length -1)
                        $(this).addClass("disabled");
                    else
                        $(this).removeClass("disabled");
                }
            });
        },

        // Update span width of columns in each row of PageBuilder at Page Load
        // Updated by arif
        updateSpanWidthPBDL:function(self, this_wrapper, totalWidth){
            
            this_wrapper.find(".jsn-row-container.outer").each(function(){
                totalWidth = $(this).width() ;
                var countColumn = $(this).find(".jsn-column-container.outer").length;
                //console.log(this , 'col count : ',countColumn);
                //console.log(1);
                self.updateSpanWidth(countColumn, totalWidth, $(this));
            });
            
            this_wrapper.find(".jsn-row-container.inner").each(function(){
                
                totalWidth = $(this).width() ;
                
                var countColumn = $(this).find(".jsn-column-container.inner").length;
                //console.log(this , 'col count : ',countColumn);
                //console.log(2);
                self.updateSpanWidth(countColumn, totalWidth, $(this));
            });
            
            
        },

        // Update span width of columns in each row
        updateSpanWidth:function(countColumn, totalWidth, parentForm){
            //console.log(countColumn, totalWidth, parentForm);
            //12px is width of the resizeable div
            
            if(parentForm.hasClass('outer')){
                var column_type = '.outer';
            }else{
                var column_type = '.inner';
            }
            
            countColumn = parentForm.find(".jsn-column-container" + column_type).size();
            
            totalWidth = parentForm.width();
            var seperateWidth = (countColumn - 1) * 12;
            var remainWidth = totalWidth - seperateWidth;
            //Updated by arif

            //console.log(parentForm,countColumn,totalWidth);
            
            parentForm.find(".jsn-column-container" + column_type).each(function (i) {
                //console.log(4);
                var selfSpan = $(this).find(".jsn-column-content"+ column_type).attr("data-column-class").replace('span','');
                //console.log(this , '-----------' + selfSpan);
                if(i == parentForm.find(".jsn-column-container" + column_type).length - 1)
                    $(this).find('.jsn-column').css('width', Math.ceil(parseInt(selfSpan)*remainWidth/12) + 'px');
                else
                    $(this).find('.jsn-column').css('width', Math.floor(parseInt(selfSpan)*remainWidth/12) + 'px');
            })
        },

        // Add Column
        addColumn:function(column_html){
            var self = this;
            this.wrapper.delegate(this.addcolumns,"click",function(){
                
                
                
                var parentForm = $(this).closest(".jsn-row-container");
                
                
                //console.log('parents of column : ' , parentForm);
                
                if(parentForm.hasClass('outer')){
                    var column_type = '.outer';
                }else{
                    var column_type = '.inner';
                }
                
                //console.log(column_type);
                
                var countColumn = parentForm.find(".jsn-column-container"+column_type).length;
                
                //console.log(this,parentForm,column_type,countColumn);

                
                //console.log(column_type + ':' + countColumn);
                
                if (countColumn < 12) {
                    countColumn += 1;
                    var span = parseInt(12 / countColumn);
                    var exclude_span = (12 % countColumn != 0)? span + (12 % countColumn) : span;
                    //console.log(span,exclude_span);
                    // update span old columns
                    parentForm.find(".jsn-column-container"+column_type).each(function () {
                        
                        var $_this = $_this_col = $_this_sc = $_this_col_cont = column_html_code = null;
                        
                        $_this = $(this);
                        
                        
                        
                        $_this_col = $('.jsn-column'+column_type , $_this);
                        
                        
                        $_this_sc = $('textarea'+column_type+'[name="shortcode_content[]"]' , $_this);
                        
                        $_this_col_cont =  $('.jsn-column-content'+column_type , $_this);
                        
                        //console.log($_this , $_this_col , $_this_sc , $_this_col_cont);
                        
                        //console.log($_this_col,$_this_sc,$_this_col_cont);
                        //console.log($_this_col.attr('class'),$_this_sc.text(),$_this_col_cont.attr('data-column-class'));
                        
                        $_this_col.attr('class', $_this_col.attr('class').replace(/span[0-9]{1,2}/g, 'span'+span));
                        $_this_sc.text($_this_sc.text().replace(/span[0-9]{1,2}/g, 'span'+span));
                        $_this_col_cont.attr('data-column-class', 'span'+span);
                        
                        //console.log($_this_col.attr('class'),$_this_sc.text(),$_this_col_cont.attr('data-column-class'));
                        //$(this).attr('class', $(this).attr('class').replace(/span[0-9]{1,2}/g, 'span'+span));
                        //$(this).html($(this).html().replace(/span[0-9]{1,2}/g, 'span'+span));
                        
                    });

                    // update span new column
                    //column_html_code = column_html.replace(/span[0-9]{1,2}/g, 'span'+exclude_span);
                    
                    if(column_type == '.inner'){
                        column_html = $('#tmpl-vs_innercolumn').html();
                        //column_html_code = column_html_code.replace(/span[0-9]{1,2}/g, 'span'+exclude_span);
                    }else{
                        column_html = $("#tmpl-vs_column").html()
                    }
                                        
                    $_this = $_this_col = $_this_sc = $_this_col_cont = null;
                        
                    $_this = $(column_html);
                    
                    
                    
                    $_this_col = $('.jsn-column'+column_type , $_this);
                     
                    
                    $_this_sc = $('textarea'+column_type+'[name="shortcode_content[]"]' , $_this);
                    
                    $_this_col_cont =  $('.jsn-column-content'+column_type , $_this); 
                    
                    //console.log($_this , $_this_col , $_this_sc , $_this_col_cont);
                    
                    //console.log($_this_col,$_this_sc,$_this_col_cont);
                    //console.log($_this_col.attr('class'),$_this_sc.text(),$_this_col_cont.attr('data-column-class'));
                    
                    $_this_col.attr('class', $_this_col.attr('class').replace(/span[0-9]{1,2}/g, 'span'+exclude_span));
                    $_this_sc.text($_this_sc.text().replace(/span[0-9]{1,2}/g, 'span'+exclude_span));
                    $_this_col_cont.attr('data-column-class', 'span'+exclude_span);
                                        
                    // add new column
                    parentForm.find(".vs-row-content"+column_type).append($_this);

                    // update width for all columns
                    self.updateSpanWidth(countColumn, self.maxWidth, parentForm);
                }
                // actiave resizable for columns
                self.initResizable(countColumn);
                self.wrapper.trigger('vs-pagebuilder-layout-changed', [parentForm]);
            });
        },

        // Confirm message when delete item
        removeConfirmMsg:function(item, type, column_to_row, callback){
            var self = this;
            var msg = "";
            var show_confirm = 1;
            switch(type){
                case 'row':
                    if(item.find('.jsn-column-content').find('.shortcode-container').length == 0)
                        show_confirm = 0;
                    msg = Vs_Translate.delete_row;
                    break;
                case 'column':
                    var check_item = (column_to_row != null) ? column_to_row : item;
                    if(check_item.find('.shortcode-container').length == 0)
                        show_confirm = 0;
                    msg = Vs_Translate.delete_column;
                    break;
                default:
                    msg = Vs_Translate.delete_element;
            }

            var confirm_ = show_confirm ? confirm(msg) : true;
            if(confirm_){
                if(type == 'row'){
                    item.animate({opacity:0},300,self.effect,function(){
                        item.animate({height:0},300,self.effect,function(){
                            item.remove();
                            self.moveItemDisable(self.wrapper);
                        });
                    });
                }
                else if(type == 'column'){
                    item.animate({height:0},500,self.effect,function(){
                        item.remove();
                        if(callback != null) callback();
                    });
                }
                else
                    item.remove();
                return true;
            }
            else
                return false;
        },

        // Remove Row/Column/Element Handle
        removeItem:function(){
            var self = this;
            var this_wrapper = this.wrapper;
            this.wrapper.delegate(this.deletebtn,"click",function(){
                if($(this).hasClass('row')){
                    self.removeConfirmMsg($(this).parents(".jsn-row-container.outer"), 'row');
                    self.wrapper.trigger('vs-pagebuilder-layout-changed', [parentForm]);
                }else if($(this).hasClass('innerrow')){
                    self.removeConfirmMsg($(this).parents(".jsn-row-container.inner").parent(), 'row');
                    self.wrapper.trigger('vs-pagebuilder-layout-changed', [parentForm]);
                }
                else if($(this).hasClass('column')){
                    var col_type = self.getLayoutType($(this));
                    var totalWidth = this_wrapper.width();
                    var parentForm = $(this).parents(".jsn-row-container" + col_type);
                    var countColumn = parentForm.find(".jsn-column-container" + col_type).length;
                    countColumn -= 1;
                    if(countColumn == 0){
                        // remove this row
                        if(col_type == '.inner')
                            parentForm = parentForm.parent();    
                        self.removeConfirmMsg(parentForm, 'column', $(this).parents(".jsn-column-container" + col_type));
                        self.wrapper.trigger('vs-pagebuilder-layout-changed', [parentForm]);
                        return true;
                    }
                    var span = parseInt(12 / countColumn);
                    var exclude_span = (12 % countColumn != 0)? span + (12 % countColumn) : span;

                    // remove current column
                    if(!self.removeConfirmMsg($(this).parents(".jsn-column-container" + col_type), 'column', null, function(){
                        // update span remain columns
                        parentForm.find(".jsn-column-container" + col_type).each(function () {
                            
                            $_this = $(this);
                            $_this_col = $('.jsn-column'+col_type , $_this);
                            $_this_sc = $('textarea'+col_type+'[name="shortcode_content[]"]' , $_this);
                            $_this_col_cont =  $('.jsn-column-content'+col_type , $_this);

                            
                            $_this_col.attr('class', $_this_col.attr('class').replace(/span[0-9]{1,2}/g, 'span'+span));
                            $_this_sc.text($_this_sc.text().replace(/span[0-9]{1,2}/g, 'span'+span));
                            $_this_col_cont.attr('data-column-class', 'span'+span);
                            
                            
                        });

                        // update span last column
                        //console.log(8,parentForm.find(".jsn-column-container" + col_type).last());
                        
                        //parentForm.find(".jsn-column-container" + col_type).last().html(parentForm.find(".jsn-column-container"+col_type).last().html().replace(/span[0-9]{1,2}/g, 'span'+exclude_span));
                        /*
                        $_this = $_this_col = $_this_sc = $_this_col_cont = null;
                        
                        $_this = parentForm.find(".jsn-column-container" + col_type).last();
                        $_this_col = $('.jsn-column'+col_type , $_this);
                        $_this_sc = $('textarea'+col_type+'[name="shortcode_content[]"]' , $_this);

                        $_this_col_cont =  $('.jsn-column-content'+col_type);
                        
                        console.log($_this_col_cont);


                        $_this_col.attr('class', $_this_col.attr('class').replace(/span[0-9]{1,2}/g, 'span'+span));
                        $_this_sc.text($_this_sc.text().replace(/span[0-9]{1,2}/g, 'span'+span));
                        $_this_col_cont.attr('data-column-class', 'span'+span);
                        */
                        // update width for all columns
                        self.updateSpanWidth(countColumn, totalWidth, parentForm);
                        // actiave resizable for columns
                        self.initResizable(countColumn);
                        self.wrapper.trigger('vs-pagebuilder-layout-changed', [parentForm]);
                    }))
                        return false;
                }

                self.updateSpanWidthPBDL(self, self.wrapper, $("#form-container").width());

            });
        },

        // Get element's dimension
        getBoxStyle:function(element){
            var style = {
                width:element.width(),
                height:element.height(),
                outerHeight:element.outerHeight(),
                outerWidth:element.outerWidth(),
                offset:element.offset(),
                margin:{
                    left:parseInt(element.css('margin-left')),
                    right:parseInt(element.css('margin-right')),
                    top:parseInt(element.css('margin-top')),
                    bottom:parseInt(element.css('margin-bottom'))
                },
                padding:{
                    left:parseInt(element.css('padding-left')),
                    right:parseInt(element.css('padding-right')),
                    top:parseInt(element.css('padding-top')),
                    bottom:parseInt(element.css('padding-bottom'))
                }
            };

            return style;
        },

        // Sortable Element
        sortableElement:function(){
        	var self	= this;
            $(".jsn-element-container").livequery(function(){
                $(this).sortable({
                    connectWith: ".jsn-element-container",
                    placeholder: "ui-state-highlight",
                    stop: function (e, ui){
                    	self.wrapper.trigger('vs-pagebuilder-layout-changed', [ui.item]);
                    }
                })
            })
            $(".jsn-element-container").disableSelection();
        },

        // show popover box
        showPopover:function(box, e, self, this_, callback1, callback2){
            $(document).trigger('click');
            if(box.is(':animated')) return;
            e.stopPropagation();
            box.hide();
            box.fadeIn(500);

            if(callback1)
                callback1();

            // show popover
            var elmStylePopover = self.getBoxStyle(box.find(".popover")),
            parentStyle = self.getBoxStyle(this_),
            offset_ = {};
            offset_.left = parentStyle.offset.left - elmStylePopover.outerWidth / 2 + parentStyle.outerWidth / 2;
            offset_.top = parentStyle.offset.top - elmStylePopover.height;
            // check if is first row or not
            var row_idx= $("#form-container .jsn-row-container").index(this_.parents('.jsn-row-container'));
            var element_in_col= this_.parent('.jsn-column-content').find('.jsn-element').length;
            offset_.top = (row_idx == 0 && element_in_col < 3) ? (offset_.top + 40) : offset_.top;
            box.offset(offset_).click(function (e) {
                e.stopPropagation();
            });
            if($(window).height() > elmStylePopover.height){
                $('html, body').animate({scrollTop: offset_.top - 60}, 'fast');
            }
            $(document).click(function(e){
                if (e.button == 0) {
                    box.hide();
                }
            });

            if(callback2)
                callback2();
        },

        // Show Add Elements Box
        addElement:function(){
            var self = this;
            var box = $("#vs-add-element");
            this.wrapper.delegate(this.addelements,"click",function(e){
                self.showPopover(box, e, self, $(this), function(){
                    // filter
                    var filter_select = box.find("select.jsn-filter-button");
                    filter_select.select2({
                        minimumResultsForSearch:99
                    });

                    if($("#jsn-quicksearch-field").val() != ''){
                        $("#reset-search-btn").trigger("click");
                    }
                    else
                        self.elementFilter(filter_select.val(), 'data-type');

                    $("#jsn-quicksearch-field").focus();

                }, function(){
                    // trigger this (call 2 times)
                    self.updateSpanWidthPBDL(self, self.wrapper, $("#form-container").width());
                    self.updateSpanWidthPBDL(self, self.wrapper, $("#form-container").width());
                });
            })
        },

        // Show Add Layout Box
        showAddLayoutBox:function(){
            var self = this;
            var box = $("#vs-add-layout");
            $('#premade-layout').click(function(e){
                self.showPopover(box, e, self, $(this));
            });
            // toggle Save/Upload layout form
            $('.layout-action').click(function(e){
                $(this).toggleClass('hidden');
                $(this).next('.layout-toggle-form').toggleClass('hidden');
            });
        },

        // Save layout
        showSaveLayoutBox:function(){
            $('#vs-pb-save-layout').click(function(e){
                $(this).toggle();
                $('#vs-pb-layout-form').toggleClass('hidden');
            });
        },

        // Search elements in "Add Element" Box
        searchElement:function(){
            var self = this;
            $.fn.delayKeyup = function (callback, ms) {
                var timer = 0;
                var el = $(this);
                $(this).keyup(function () {
                    clearTimeout(timer);
                    timer = setTimeout(function () {
                        callback(el)
                    }, ms);
                });
                return $(this);
            };
            $('#jsn-quicksearch-field').keydown(function (e) {
                if(e.which == 13)
                    return false;
            });
            $('#jsn-quicksearch-field').delayKeyup(function(el) {
                if($(el).val() != '')
                    $("#reset-search-btn").show();
                else
                    $("#reset-search-btn").hide();

                ///self.filterElement($(el).val(), 'value');
                self.elementFilter($(el).val().toLowerCase());
            }, 500);
            $('#vs-add-element .jsn-filter-button').change(function() {
                ///self.filterElement($(this).val(), 'type');
                self.elementFilter($(this).val(), 'data-type');
            })
            $("#reset-search-btn").click(function(){
                ///self.filterElement("all");
                self.elementFilter('');
                $(this).hide();
                $("#jsn-quicksearch-field").val("");
            })
        },
        // animation filter
        elementFilter:function(value, data){
            var $container = $('#vs-add-element .jsn-items-list');
            var selector = '.jsn-item';
            var item = selector;
            if(data == null) data = 'data-value';
            if(value != '' && value != 'all')
                selector += '['+data+'*="'+value+'"]';
            if(data == 'data-value'){
                selector += '[data-type="'+$('#vs-add-element select.jsn-filter-button').val()+'"]';
            }
            $container.find(item).fadeOut(100);
            $container.find(selector).fadeIn();
            
            if (value == 'shortcode') {
            	$('#jsn-quicksearch-field').hide(100);
            }else{
            	if ($('#jsn-quicksearch-field').css('display') == 'none') {
            		$('#jsn-quicksearch-field').show(100);
            	}
            }
        },

        // Filter elements in "Add Element" Box
        filterElement:function(value, filter_data){
            var resultsFilter = $('#vs-add-element .jsn-items-list');
            if (value != "all") {
                $(resultsFilter).find("li").hide();
                $(resultsFilter).find("li").each(function () {
                    var textField = (filter_data == 'value') ? $(this).attr("data-value").toLowerCase() : $(this).attr("data-type").toLowerCase();
                    if (textField.search(value.toLowerCase()) === -1) {
                        $(this).hide();
                    } else {
                        $(this).fadeIn(500);
                    }
                });
            }
            else $(resultsFilter).find("li").show();
        }
    };


    $(document).ready(function() {
        // VS PageBuilder: get textarea content
        var vs_pg_html = '';
        // VS PageBuilder: check if content has changed
        var _change_pagebuilder = 1;
        // Classic Editor: check if content has changed
        var _change_editor = 1;
        // Classic Editor: get content of Text tab
        var text_content = $('#vs_editor_tab1 #content').val();

        var layout;

        // Classic Editor: get content of Text tab
        $('#vs_editor_tab1 #content').bind('input propertychange', function(){
            _change_editor = 1;
            text_content = $(this).val();
        });

        // switch tab: Classic editor , VS PageBuilder
        $('#vs_editor_tabs a').click(function (e, init_layout) {
            e.preventDefault();
            var hash = this.hash;
            // check if this is first time run
            init_layout = (init_layout != null) ? init_layout : false;

            $(this).tab('show');

            // init VS PageBuilder
            if(this.hash == '#vs_editor_tab2' && layout == null){
                layout = new JSNLayoutCustomizer();
                layout.init($("#form-container .jsn-row-container"));
            }
            // if it is first time run, don't sync content
            if(init_layout)
                return;

            // VS PageBuilder is deactivate, stop processing
            if($('#vs_deactivate_pb').val() == "1")
                return;

            // synchronous content from Classic editor to VS PageBuilder
            // store content of current Tab
            var tab_content = '';
            switch (hash) {

                // VS PageBuilder -> Classic Editor
                case '#vs_editor_tab1':
                    // check if content of VS PageBuilder is changed
                    var old_vs_pg_html = vs_pg_html;

                    // get Raw shortcodes content in VS PageBuilder tab
                    var vs_pb_textarea_content = $('#form-container textarea').serialize();

                    // update value for vs_pg_html
                    if(vs_pg_html == '' || vs_pg_html != vs_pb_textarea_content){
                        vs_pg_html = vs_pb_textarea_content;
                    }

                    // check if value is changed
                    if(old_vs_pg_html != vs_pg_html){
                        _change_pagebuilder = 1;
                    }

                    // Check if content of 2 tabs are same
                    if($("#vs_editor_tab1 #content").val() == tab_content) {
                        _change_pagebuilder = 0;
                    }

                    // if changed
                    if(_change_pagebuilder){

                        // get Nice shortcodes content in VS PageBuilder tab
                        $("#form-container textarea[name^='shortcode_content']").each(function(){
                            tab_content += $(this).val();
                        });

                        // disable WP Update button
                        $('#publishing-action #publish').attr('disabled', true);

                        // remove placeholder text which was inserted to &lt; and &gt;
                        tab_content = vs_pb_remove_placeholder(tab_content, 'wrapper_append', '');

                        // update Classic Editor content
                        $.HandleElement.updateClassicEditor(tab_content, function(){

                            // reset global variable
                            tab_content = '';
                            _change_pagebuilder = 0;

                            // reset condition variables
                            _change_editor = 0;
                            text_content = tab_content;
                            $('#vs-tinymce-change').val('0');
                        });
                    }

                    break;

                // Classic Editor -> VS PageBuilder
                case '#vs_editor_tab2':

                    // Check if content of Classic Editor Text / Visual has changed
                    if(_change_editor || $('#vs-tinymce-change').val() == "1"){

                        // remove Shortcode content which is not wrapped in row & column
                        $('#form-container #vs-tinymce-change').nextAll( ".jsn-item" ).remove();

                        // if content is empty, try to get again
                        if( ! _change_editor && tinymce.get('content') ) {
                            text_content = tinymce.get('content').getContent();
                        } else {
                            text_content = $('#vs_editor_tab1 #content').val();
                        }

                        // update latest content value
                        tab_content = text_content;

                        // update VS PageBuilder content
                        $.HandleElement.updatePageBuilder(tab_content, function(){
                            // reset VS PageBuilder Layout manager
                            layout.fnReset(layout,true);
                            layout.moveItemDisable(layout.wrapper);
                        });

                        // reset condition variables
                        text_content = tab_content = '';
                        _change_editor = 0;
                        $('#vs-tinymce-change').val('0');
                    }

                    break;
            }
        })
    })


})(jQuery);