var addEvents = function(namespace, textField, fileField) {
        AUI().use('aui-base', function (A) {
            A.one("#" + namespace + fileField).on('change', function () {
                var input = A.one("#" + namespace + textField);

                var inputFile = A.one("#" + namespace + fileField);
                var fileList = inputFile.getDOM().files;
                var numFiles = fileList ? fileList.length : 1;
                var label = inputFile.val().replace(/\\/g, '/').replace(/.*\//, '');

                input.set('disabled', numFiles > 0);
            });

            A.one("#" + namespace + textField).on('change', function () {
                var input = A.one("#" + namespace + fileField);
                var textInput = A.one("#" + namespace + textField);
                input.set('disabled', textInput.val()!="" && textInput.val()!=null);
            });
        })
}

/**
 * This module generates the search box widget wizard
 *
 * @module searchBoxWidgetWizard
 * @requires wizardTools
 */
YUI.add('searchBoxWidgetWizard', function (Y) {
    var
            /**
             * Static constant to refer field 'name'
             *
             * @property FIELD_NAME
             * @type String
             * @static
             * @final
             */
            FIELD_NAME = 'name',
            FIELD_DESCRIPTION = 'description',

            /**
             * Static constant to refer field 'resultsPage'
             *
             * @property FIELD_RESULTS_PAGE
             * @type String
             * @static
             * @final
             */
            FIELD_RESULTS_PAGE = 'resultsPage',

            /**
             * Static constant to refer field 'targetPage'
             *
             * @property FIELD_TARGET_PAGE
             * @type String
             * @static
             * @final
             */
            FIELD_TARGET_PAGE = 'targetPage',

            /**
             * Static constant to refer field 'criteria'
             *
             * @property FIELD_CRITERIA
             * @type String
             * @static
             * @final
             */
            FIELD_CRITERIA = 'criteria',

            /**
             * Defines the value that specifies that the search is redirected to eu law and publications website
             *
             * @property RESULTS_PAGE_EU_LAW
             * @type {string}
             * @static
             * @final
             */
            RESULTS_PAGE_EU_LAW = 'a',

            /**
             * Defines the value that specifies that the search is redirected to the page specified by {{#crossLink 'SearchBoxWidgetWizard/targetPage:attribute'}}{{/crossLink}}
             *
             * @property RESULTS_PAGE_OWN
             * @type {string}
             * @static
             * @final
             */
            RESULTS_PAGE_OWN = 'b',

            /**
             * Defines text criteria type
             *
             * @property CRITERIA_TEXT
             * @type {string}
             * @static
             * @final
             */
            CRITERIA_TEXT = 'text',

            /**
             * Defines collection criteria type
             *
             * @property CRITERIA_COLLECTION
             * @type {string}
             * @static
             * @final
             */
            CRITERIA_COLLECTION = 'collection',

            /**
             * Defines subject criteria type
             *
             * @property CRITERIA_SUBJECT
             * @type {string}
             * @static
             * @final
             */
            CRITERIA_SUBJECT = 'subject',

            /**
             * Defines author criteria type
             *
             * @property CRITERIA_AUTHOR
             * @type {string}
             * @static
             * @final
             */
            CRITERIA_AUTHOR = 'author',

            /**
             * Defines language criteria type
             *
             * @property CRITERIA_LANGUAGE
             * @type {string}
             * @static
             * @final
             */
            CRITERIA_LANGUAGE = 'language',

            /**
             * Defines format criteria type
             *
             * @property CRITERIA_FORMAT
             * @type {string}
             * @static
             * @final
             */
            CRITERIA_FORMAT = 'format',

            /**
             * Defines date criteria type
             *
             * @property CRITERIA_DATE
             * @type {string}
             * @static
             * @final
             */
            CRITERIA_DATE = 'date',

            /**
             * Date format th be displayed in the placeholder. This is European date format
             * @type {string}
             */
            DATE_FORMAT_PLACEHOLDER = 'yyyy/mm/dd',

            /**
             * Date format used to parse the date, this corresponds to the European date format
             * @type {string}
             */
            DATE_FORMAT_PATTERN = '%Y/%m/%d',

            /**
             * Keeps dd subscription so it will be removed when plugin is unloaded
             *
             * @property SUBSCRIPTION_DD_OVER
             * @type {string}
             * @static
             */
            SUBSCRIPTION_DD_OVER,

            /**
             * Keeps dd subscription so it will be removed when plugin is unloaded
             *
             * @property SUBSCRIPTION_DD_DRAG
             * @type {string}
             * @static
             */
            SUBSCRIPTION_DD_DRAG,

            /**
             * Keeps dd subscription so it will be removed when plugin is unloaded
             *
             * @property SUBSCRIPTION_DD_START
             * @type {string}
             * @static
             */
            SUBSCRIPTION_DD_START,

            /**
             * Keeps dd subscription so it will be removed when plugin is unloaded
             *
             * @property SUBSCRIPTION_DD_END
             * @type {string}
             * @static
             */
            SUBSCRIPTION_DD_END,

            /**
             * Keeps dd subscription so it will be removed when plugin is unloaded
             *
             * @property SUBSCRIPTION_DD_DROP_HIT
             * @type {string}
             * @static
             */
            SUBSCRIPTION_DD_DROP_HIT,

            /**
             * Keeps a list of available criterias for search
             *
             * @property AVAILABLE_CRITERIA
             * @type {string}
             * @static
             * @final
             */
            AVAILABLE_CRITERIA = [
                {
                    label: 'TextSearch',
                    type: CRITERIA_TEXT,
                    defaultVisible: true,
                    defaultMandatory: true
                },
                {
                    label: 'Collection',
                    type: CRITERIA_COLLECTION,
                    defaultVisible: true,
                    defaultMandatory: false,
                    valuesCallback: '_getAvailableCollections',
                    multiple: true
                },
                {
                    label: 'Subject',
                    type: CRITERIA_SUBJECT,
                    defaultVisible: true,
                    defaultMandatory: false,
                    valuesCallback: '_getAllSubjects',
                    useAjax: true
                },
                {
                    label: 'Author',
                    type: CRITERIA_AUTHOR,
                    defaultVisible: true,
                    defaultMandatory: false,
                    valuesCallback: '_getAllAuthors',
                    useAjax: true
                },
                {
                    label: 'Language',
                    type: CRITERIA_LANGUAGE,
                    defaultVisible: true,
                    defaultMandatory: false,
                    valuesCallback: '_getAvailableLanguages',
                    multiple: false
                },
                {
                    label: 'Format',
                    type: CRITERIA_FORMAT,
                    defaultVisible: true,
                    defaultMandatory: false,
                    valuesCallback: '_getAvailableFormats',
                    multiple: true
                },
                {
                    label: 'Date',
                    type: CRITERIA_DATE,
                    defaultVisible: true,
                    defaultMandatory: false,
                    dateBetween: true
                }
            ],

            /**
             * Caches the available languages
             *
             * @property CRITERIA_AVAILABLE_LANGUAGES
             * @type {string}
             * @static
             */
            CRITERIA_AVAILABLE_LANGUAGES,

            /**
             * Caches the available formats
             *
             * @property CRITERIA_AVAILABLE_FORMATS
             * @type {string}
             * @static
             */
            CRITERIA_AVAILABLE_FORMATS,

            /**
             * Caches the available collections
             *
             * @property CRITERIA_AVAILABLE_COLLECTIONS
             * @type {string}
             * @static
             */
            CRITERIA_AVAILABLE_COLLECTIONS,

            /**
             * Static property to check if the dragged element is dragged up
             *
             * @property goingUp
             * @type {boolean}
             * @static
             */
            goingUp = false,

            /**
             * Static property to check Y position of dragged element
             *
             * @property lastY
             * @type {int}
             * @static
             */
            lastY = 0;

    /**
     * Generates the dom and dom events for search box wizard
     *
     * @param cfg
     * @constructor
     * @class SearchBoxWidgetWizard
     * @extends AbstractWizard
     */
    function SearchBoxWidgetWizard(cfg) {
        SearchBoxWidgetWizard.superclass.constructor.apply(this, arguments);
    }

    SearchBoxWidgetWizard.NAME = 'SearchBoxWidgetWizard';
    SearchBoxWidgetWizard.NS = 'SearchBoxWidgetWizard';

    SearchBoxWidgetWizard.ATTRS = {

        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },

        /**
         * Keeps the selected option by the user, referring to form action url
         *
         * @attribute resultsPage
         * @type String
         * @default 'a'
         */
        resultsPage: {
            value: RESULTS_PAGE_EU_LAW
        },

        /**
         * Keeps the target page of the search box
         *
         * @attribute targetPage
         * @type String
         * @default {}
         */
        targetPage: {
            value: ''
        },

        /**
         * Appearance tab
         */
        setAppearanceTabs: null,

        /**
         * Array of objects with the following structure
         *      {
         *          type: 'CriteriaType',
         *          visibleToUsers: true,
         *          criteriaMandatory: true,
         *          defaultValue: '',
         *          cssClass: '',
         *          weight: ''
         *      }
         *
         * @attribute criteria
         * @type Array
         * @default []
         */
        criteria: {
            value: []
        }
    };
    Y.extend(SearchBoxWidgetWizard, Y.BaseWidgetList, {
        initWizard: function () {
            var instance = this,
                    host = this.get('host'),
                    isEdit = instance.get('widgetId') > 0;
            instance.set('widgetType', '1');
            instance._addDropDownEvents();
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general'),
                    instance.t('searchResult.appearance'),
                    instance.t('statistics.search.form')
                ],
                children: [
                    instance.getGeneralSettings(),
                    instance.getAppearanceSettings(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();

            var isExistentWidget = (parseInt(instance.get('widgetId')) > 0);
            new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + "_buttonRow",
                        children: [
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' disabled' : ''),
                                htmlContent: instance.t('searchBox.save'),
                                onClick: function (e) {
                                    if (!instance.validateWidget()) {
                                        return;
                                    }
                                    instance.convertBasicAppearanceObjListToJson();
                                    instance.doSaveWidget();
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right get-button' + (!isExistentWidget ? ' hidden' : ''),
                                htmlContent: instance.t('searchBox.getCode'),
                                onClick: function (e) {
                                    instance.convertBasicAppearanceObjListToJson();
                                    instance.doGetWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' hidden' : ''),
                                htmlContent: instance.t('baseWidgetList.cancel'),
                                onClick: function (e) {
                                    instance.doReturnToMyWidgets();
                                }
                            })
                        ]
                    })
                ]
            }).render(host);

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });

            var criteriaList = host.one('.criteria-list'),
                    id = criteriaList.get('id');
            var lis = host.one('.criteria-list').all('.available-criteria');
            lis.each(function (v, k) {
                var dd = new Y.DD.Drag({
                    node: v,
                    target: {
                        padding: '0 0 0 20'
                    }
                }).plug(Y.Plugin.DDProxy, {
                    moveOnEnd: false
                }).plug(Y.Plugin.DDConstrained, {
                    constrain2node: '#' + id
                });
            });

            //Create simple targets for the 2 lists.
            new Y.DD.Drop({
                node: criteriaList
            });
        },

        /**
         * Retruns DOM objects for the general tab - the widgets components
         * @returns {Y.PanelElement} - YUI object that neeeds to be rendered
         */
        getGeneralSettings: function () {
            var instance = this;
            var returnOBJ;

            returnOBJ = new Y.PanelElement({
                wrapperCssClass: 'tab-pane active',
                id: 'tab-1',
                children: [
                    new Y.InputElement({
                        label: instance.t('searchBox.name'),
                        name: FIELD_NAME,
                        modelInstance: instance,
                        placeholder: instance.t('baseWidgetList.name.placeholder'),
                        cssClass: 'widget-input',
                        required: true,
                        validateFunction: function () {
                            instance.validateWidget()
                        }
                    }),
                    new Y.InputElement({
                        label: instance.t('searchBox.description'),
                        name: FIELD_DESCRIPTION,
                        placeholder: instance.t('baseWidgetList.description.placeholder'),
                        modelInstance: instance,
                        cssClass: 'widget-input'
                    }),
                    instance.getLanguageSelector(),
                    instance._createCriteriaElements(),
                    new Y.HtmlElement({
                        label: instance.t('searchBox.resultsPage'),
                        children: [
                            new Y.RadioElement({
                                label: instance.t('searchBox.useTheResultsPageOfEuLawAndPublicationsWebsite'),
                                value: RESULTS_PAGE_EU_LAW,
                                modelInstance: instance,
                                name: FIELD_RESULTS_PAGE
                            }),
                            new Y.RadioElement({
                                label: instance.t('searchBox.ownResultsPage'),
                                value: RESULTS_PAGE_OWN,
                                modelInstance: instance,
                                name: FIELD_RESULTS_PAGE
                            })
                        ]
                    }),
                    new Y.InputElement({
                        label: instance.t('searchBox.targetPage'),
                        name: FIELD_TARGET_PAGE,
                        modelInstance: instance
                    })
                ]
            });

            return returnOBJ;
        },

        /**
         * Retunrns the DOM objects for the Appearance Tab
         * @returns {Y.PanelElement} - YUI elements that need to be rendered
         */
        getAppearanceSettings: function () {
            var instance = this;
            var tab;

            var basicConfiguration = null;
            var advancedConfiguration = null;

            if (instance.get('widgetAppearance') != undefined && instance.get('widgetAppearance') != null) {
                basicConfiguration = instance.get('widgetAppearance');
            }

            /**
             * if parameters for getDisplayAppearence() doesn't exists, provide null as parameter.             *
             * @type {Y.TabView}
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(basicConfiguration, advancedConfiguration, true, false);


            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });


            return tab;
        },

        getStatisticsTable: function () {
            var instance = this, tab;
            var isEdit = instance.get('widgetId') > 0;

            var tableStatistics = [];

            tableStatistics.push(instance.getTableStatistics());

            if (isEdit) {
                tableStatistics.push(instance.getTableDetaliedStatistics());
            }


            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: tableStatistics
                    }),
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        // label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        htmlContent: '<a class="pull-right" href="' + Liferay.portal2012[instance.get('namespace') + "downloadStatisticsSearchForm"] + '">' + instance.t('statistics.download') + '</a>'
                    })
                ]
            });

            return tab;
        },

        getTableStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSearchForm"],
                    data = [],
                    columns = [],
                    i,
                    len;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement;

            if (widgetList) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: parseInt(widgetElement.visits),
                        clicks: parseInt(widgetElement.clicksPerm + widgetElement.clicksSearch)
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            if (!isEdit) {
                table.set('rowsPerPage', 25);
                table.set('pageSizes', [10, 25, 50])
                table.set('paginatorLocation', ['footer']);
            }

            return table;
        },

        getTableDetaliedStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSearchForm"],
                    data = [],
                    columns = [],
                    i, j,
                    len, lenJ;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement, detailsWidgetElement = [];


            if (widgetList) {
                for (i = 0, len = (widgetList.length - 1); i < len; i++) {
                    if (widgetList[i].publicationStatisticsDTOList) {
                        detailsWidgetElement = widgetList[i].publicationStatisticsDTOList;

                        for (j = 0, lenJ = detailsWidgetElement.length; j < lenJ; j++) {
                            widgetElement = detailsWidgetElement[j];
                            data.push({
                                searchTerms: widgetElement.searchTerms,
                                noSearches: widgetElement.noSearches

                            });
                        }
                    }
                }
            }

            columns = [
                {
                    key: 'searchTerms',
                    label: instance.t('statistics.table.search.terms'),
                    width: '80%',
                    className: 'numeric'
                },
                {
                    key: 'noSearches',
                    width: '20%',
                    label: instance.t('statistics.table.number.searches'),
                    sortable: true
                }

            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 25);
            table.set('pageSizes', [10, 25, 50])
            table.set('paginatorLocation', ['footer']);


            return table;
        },

        destructWizard: function () {
            if (SUBSCRIPTION_DD_DRAG) {
                SUBSCRIPTION_DD_DRAG.detach();
            }
            if (SUBSCRIPTION_DD_DROP_HIT) {
                SUBSCRIPTION_DD_DROP_HIT.detach();
            }
            if (SUBSCRIPTION_DD_END) {
                SUBSCRIPTION_DD_END.detach();
            }
            if (SUBSCRIPTION_DD_OVER) {
                SUBSCRIPTION_DD_OVER.detach();
            }
            if (SUBSCRIPTION_DD_START) {
                SUBSCRIPTION_DD_START.detach();
            }
        },

        /**
         * Returns the DOM structure for search criteria elements, using the
         * {{#crossLink 'SearchBoxWidgetWizard/AVAILABLE_CRITERIA:property'}}{{/crossLink}} property
         *
         * @method _createCriteriaElements
         * @return {HtmlElement}
         * @private
         */
        _createCriteriaElements: function () {
            var instance = this,
                    children = [], i,
                    defaultCriteria = AVAILABLE_CRITERIA.slice(0),
                    availableCriteria = instance.get(FIELD_CRITERIA);

            defaultCriteria.sort(function (a, b) {
                var aCriteria, bCriteria;
                for (var i = 0; i < availableCriteria.length && !(aCriteria && bCriteria); i++) {
                    if (!aCriteria && availableCriteria[i].type == a.type) {
                        aCriteria = availableCriteria[i];
                    }
                    else if (!bCriteria && availableCriteria[i].type == b.type) {
                        bCriteria = availableCriteria[i];
                    }
                }
                if (!aCriteria && !bCriteria) {
                    return 0;
                }
                if (!aCriteria) {
                    return 1;
                }
                if (!bCriteria) {
                    return -1;
                }
                if (aCriteria.weight > bCriteria.weight) {
                    return 1;
                }
                else {
                    return -1;
                }
            });

            for (i = 0; i < defaultCriteria.length; i++) {
                var criteria = defaultCriteria[i],
                        wrapperCssClass = 'available-criteria',
                        selected = false;

                for (var j = 0; j < availableCriteria.length; j++) {
                    if (criteria.type == availableCriteria[j].type) {
                        selected = true;
                        break;
                    }
                }

                children.push(new Y.HtmlElement({
                    label: instance.t(criteria.label), // todo get label
                    wrapperCssClass: wrapperCssClass + (selected ? " active" : ''),

                    // Keep the criteria type in id
                    id: 'criteria_' + criteria.type,
                    children: [
                        new Y.InputElement({
                            type: 'hidden',
                            value: criteria.type,
                            cssClass: 'criteria-type'
                        }),
                        new Y.HtmlElement({
                            htmlContent: instance.t('searchBox.edit'),
                            cssClass: 'criteria-edit',
                            onClick: function (e) {
                                instance._doEditCriteria(e);
                            }
                        }),
                        new Y.CheckboxElement({
                            cssClass: 'criteria-toggle',
                            checked: selected ? 'true' : '',
                            onClick: function (e) {
                                instance._doSelectCriteria(e);
                            }
                        })
                    ]
                }));
            }

            return new Y.HtmlElement({
                label: instance.t('searchBox.searchCriteria'),
                cssClass: 'container-fluid container-fluid-legacy',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'row-legacy',
                        children: [
                            new Y.HtmlElement({
                                cssClass: 'col-xs-6 criteria-list',
                                id: instance.get('namespace') + 'criteria_selector',
                                children: children,
                                required: true,
                                validateFunction: function () {
                                    instance.validateWidget();
                                }
                            }),
                            new Y.HtmlElement({
                                cssClass: 'col-xs-6 edit-criteria',
                                children: []
                            })
                        ]
                    })
                ]
            });
        },

        validateWidget: function () {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate criteria toggles list */
            var criteriaToggles = host.one('#' + instance.get('namespace') + 'criteria_selector').all('.criteria-toggle');
            var isCriteriaValidated = false;
            criteriaToggles.each(function (criteriaToggle) {
                if (criteriaToggle.get('checked')) {
                    isCriteriaValidated = true;
                }
            });
            if (!isCriteriaValidated) {
                isValidated = false;
            }

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });


            if (isValidated) {
                actionButtons.removeClass('disabled');
            }
            else {
                actionButtons.addClass('disabled');
            }
            return isValidated;
        },

        /**
         * Returns an array of available criteria and caches the result in
         * {{#crossLink 'SearchBoxWidgetWizard/CRITERIA_AVAILABLE_COLLECTIONS:property'}}{{/crossLink}} property
         *
         * @method _getAvailableCollections
         * @return {Array} of objects of type {key : 'key', value: 'value'}
         * @private
         */
        _getAvailableCollections: function () {
            var instance = this;
            if (!CRITERIA_AVAILABLE_COLLECTIONS) {
                CRITERIA_AVAILABLE_COLLECTIONS = Liferay.portal2012[instance.get('namespace') + "criteriaAvailableCollections"];
            }

            return CRITERIA_AVAILABLE_COLLECTIONS;
        },

        /**
         * Returns an array of available languages and caches the result in
         * {{#crossLink 'SearchBoxWidgetWizard/CRITERIA_AVAILABLE_LANGUAGES:property'}}{{/crossLink}} property
         *
         * @method _getAvailableLanguages
         * @return {Array} of objects of type {key : 'key', value: 'value'}
         * @private
         */
        _getAvailableLanguages: function () {
            var instance = this;
            if (!CRITERIA_AVAILABLE_LANGUAGES) {
                CRITERIA_AVAILABLE_LANGUAGES = Liferay.portal2012[instance.get('namespace') + "criteriaAvailableLanguages"];
            }

            return CRITERIA_AVAILABLE_LANGUAGES;
        },

        /**
         * Returns an array of available formats and caches the result in
         * {{#crossLink 'SearchBoxWidgetWizard/CRITERIA_AVAILABLE_FORMATS:property'}}{{/crossLink}} property
         *
         * @method _getAvailableFormats
         * @return {Array} of objects of type {key : 'key', value: 'value'}
         * @private
         */
        _getAvailableFormats: function () {
            var instance = this;
            if (!CRITERIA_AVAILABLE_FORMATS) {
                CRITERIA_AVAILABLE_FORMATS = Liferay.portal2012[instance.get('namespace') + "criteriaAvailableFormats"];
            }

            return CRITERIA_AVAILABLE_FORMATS;
        },

        /**
         * Returns the URL used by AutoComplete to search in the server for subjects
         *
         * @method _getAllSubjects
         * @return {String}
         * @private
         */
        _getAllSubjects: function () {
            var instance = this,
                    defaultLanguage = instance.getDefaultLanguage();
            return '/o/opportal-service/autocomplete/subject?language=' + defaultLanguage + '&chars={query}';
        },

        /**
         * Returns the URL used by AutoComplete to search in the server for authors
         *
         * @method _getAllAuthors
         * @return {String}
         * @private
         */
        _getAllAuthors: function () {
            var instance = this,
                    defaultLanguage = instance.getDefaultLanguage();
            return '/o/opportal-service/autocomplete/author?language=' + defaultLanguage + '&chars={query}';
        },

        /**
         * Callback method executed when the user presses edit on a selected criteria
         *
         * @method _doEditCriteria
         * @param e
         * @private
         */
        _doEditCriteria: function (e) {
            var instance = this,
                    host = instance.get('host'),
                    editArea = host.one('.edit-criteria'),
                    criteriaSelectedElement = Y.one(e.currentTarget).ancestor("div.available-criteria"),
                    criteriaId = criteriaSelectedElement.one('.criteria-type').get('value'),
                    criteria, i, tempCriteria, selectedCriteria, valuesElement, messageBubble;
            var renderElementList = [];


            editArea.empty();

            for (i = 0; i < AVAILABLE_CRITERIA.length; i++) {
                tempCriteria = AVAILABLE_CRITERIA[i];
                if (criteriaId == tempCriteria.type) {
                    criteria = tempCriteria;
                    break;
                }
            }

            for (i = 0; i < instance.get(FIELD_CRITERIA).length; i++) {
                tempCriteria = instance.get(FIELD_CRITERIA)[i];
                if (criteriaId == tempCriteria.type) {
                    selectedCriteria = tempCriteria;
                    break;
                }
            }

            if (!criteria || !selectedCriteria) {
                return;
            }

            if (criteria.valuesCallback && !criteria.useAjax) {
                valuesElement = new Y.SelectBoxElement({
                    label: instance.t('searchBox.defaultValue'),
                    name: 'defaultValue',
                    cssClass: 'default-value',
                    options: instance[criteria.valuesCallback](),
                    value: selectedCriteria.defaultValue,
                    multiple: criteria.multiple ? true : false
                });

                if (criteria.multiple) {
                    messageBubble = new Y.HtmlElement({
                        wrapperCssClass: 'glyphicon glyphicon-asterisk',
                        cssClass: 'info-message',
                        htmlContent: instance.t('baseWidgetList.message.help')
                    });
                }
            }
            else if (criteria.valuesCallback && criteria.useAjax) {
                valuesElement = new Y.AutoCompleteElement({
                    label: instance.t('searchBox.defaultValue'),
                    name: 'defaultValue',
                    cssClass: 'default-value',
                    selectedOptions: selectedCriteria.defaultValue,
                    cacheNamespace: "searchBoxWidgetWizard" + criteria.type,
                    source: instance[criteria.valuesCallback]()
                });
            }
            else if (criteria.type == CRITERIA_DATE) {
                var valueFrom = "", valueTo = "", parts = [];
                if (selectedCriteria.defaultValue && selectedCriteria.defaultValue.length > 0) {
                    parts = selectedCriteria.defaultValue[0].split("|");
                }
                if (parts.length > 0) {
                    try {
                        valueFrom = Y.Date.format(Y.Date.parse(parts[0]), {format: DATE_FORMAT_PATTERN});
                    } catch (e) {
                        valueFrom = ""
                    }
                }
                if (parts.length > 1) {

                    try {
                        valueTo = Y.Date.format(Y.Date.parse(parts[1]), {format: DATE_FORMAT_PATTERN});
                    } catch (e) {
                        valueTo = ""
                    }
                }

                valuesElement = new Y.HtmlElement({
                    children: [
                        new Y.InputDateElement({
                            label: instance.t('searchBox.dateFrom'),
                            name: 'defaultValueFrom',
                            cssClass: 'default-value-from',
                            placeholder: DATE_FORMAT_PLACEHOLDER,
                            value: valueFrom
                        }),
                        new Y.InputDateElement({
                            label: instance.t('searchBox.dateTo'),
                            name: 'defaultValueTo',
                            cssClass: 'default-value-to',
                            placeholder: DATE_FORMAT_PLACEHOLDER,
                            value: valueTo
                        })
                    ]
                });
            }
            else {
                valuesElement = new Y.InputElement({
                    label: instance.t('searchBox.defaultValue'),
                    name: 'defaultValue',
                    cssClass: 'default-value',
                    value: selectedCriteria.defaultValue && selectedCriteria.defaultValue.length > 0 ? selectedCriteria.defaultValue[0] : ""
                });
            }

            /**
             * Construction of the render list of elements
             */

            renderElementList.push(
                    new Y.CheckboxElement({
                        label: instance.t('searchBox.visibleToUsers'),
                        name: 'visibleToUsers',
                        cssClass: 'visible-to-users',
                        value: 1,
                        checked: selectedCriteria.visibleToUsers
                    })
            );

            renderElementList.push(
                    new Y.CheckboxElement({
                        label: instance.t('searchBox.criteriaMandatory'),
                        name: 'criteriaMandatory',
                        cssClass: 'criteria-mandatory',
                        value: 1,
                        checked: selectedCriteria.criteriaMandatory
                    })
            );

            renderElementList.push(valuesElement);

            //If there is no help message
            if (messageBubble != undefined) {
                renderElementList.push(messageBubble);
            }


            renderElementList.push(
                    new Y.InputElement({
                        label: instance.t('searchBox.cssClass'),
                        name: 'cssClass',
                        cssClass: 'css-class',
                        value: selectedCriteria.cssClass
                    })
            );

            renderElementList.push(
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        children: [
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary',
                                htmlContent: instance.t('searchBox.save'),
                                onClick: function (e) {
                                    var allCriteria = instance.get(FIELD_CRITERIA);
                                    selectedCriteria.visibleToUsers = editArea.one('.visible-to-users').get('checked');
                                    selectedCriteria.criteriaMandatory = editArea.one('.criteria-mandatory').get('checked');
                                    if (criteria.valuesCallback && !criteria.useAjax) {
                                        selectedCriteria.defaultValue = editArea.one('.default-value').all('option:checked').get('value');
                                    }
                                    else if (criteria.useAjax) {
                                        selectedCriteria.defaultValue = valuesElement.get("selectedOptions");
                                    }
                                    else if (criteria.type == CRITERIA_DATE) {
                                        var valueFrom = editArea.one('.default-value-from').get('value'),
                                                valueTo = editArea.one('.default-value-to').get('value');

                                        try {
                                            valueFrom = Y.Date.parse(valueFrom).getTime() - (Y.Date.parse(valueFrom).getTimezoneOffset() * 60000);
                                        } catch (e) {
                                            valueFrom = "";
                                        }
                                        try {
                                            valueTo = Y.Date.parse(valueTo).getTime() - (Y.Date.parse(valueTo).getTimezoneOffset() * 60000);
                                        } catch (e) {
                                            valueTo = "";
                                        }
                                        selectedCriteria.defaultValue = [valueFrom + "|" + valueTo];
                                    }
                                    else {
                                        selectedCriteria.defaultValue = [editArea.one('.default-value').get('value')];
                                    }
                                    selectedCriteria.cssClass = editArea.one('.css-class').get('value');

                                    for (i = 0; i < allCriteria.length; i++) {
                                        if (selectedCriteria.type == allCriteria.type) {
                                            break;
                                        }
                                    }

                                    if (i < allCriteria.length) {
                                        allCriteria.splice(i, 1, selectedCriteria);
                                    }

                                    editArea.empty();
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn',
                                htmlContent: instance.t('searchBox.cancel'),
                                onClick: function (e) {
                                    editArea.empty();
                                }
                            })
                        ]
                    })
            )

            new Y.HtmlElement({
                label: instance.t(criteria.label),
                children: renderElementList
            }).render(editArea);
        },


        /**
         * Callback method executed when the user selects the criteria
         *
         * @method _doSelectCriteria
         * @param e
         * @private
         */
        _doSelectCriteria: function (e) {
            var instance = this,
                    criteriaSelected = Y.one(e.currentTarget).ancestor("div.available-criteria"),
                    criteriaId = criteriaSelected.one('.criteria-type').get('value'),
                    criteria, i;

            criteriaSelected.toggleClass('active');

            for (i = 0; i < AVAILABLE_CRITERIA.length; i++) {
                var tempCriteria = AVAILABLE_CRITERIA[i];
                if (criteriaId == tempCriteria.type) {
                    criteria = tempCriteria;
                    break;
                }
            }

            if (!criteria) {
                return;
            }

            if (criteriaSelected.hasClass('active')) {
                instance._doAddCriteria(criteria, criteriaSelected);
            }
            else {
                instance._doRemoveCriteria(criteria);
            }
        },

        /**
         * Adds a criteria in the {{#crossLink 'SearchBoxWidgetWizard/criteria:attribute'}}{{/crossLink}} attribute
         *
         * @method _doAddCriteria
         * @param criteria
         * @param criteriaSelected
         * @private
         */
        _doAddCriteria: function (criteria, criteriaSelected) {
            var instance = this, i,
                    availableCriteria = instance.get(FIELD_CRITERIA),
                    criteriaList = Y.one('.criteria-list').all('div.available-criteria'),
                    weight = criteriaList.indexOf(criteriaSelected);

            for (i = 0; i < availableCriteria.length; i++) {
                if (criteria.type == availableCriteria[i].type) {
                    return;
                }
            }

            availableCriteria.push({
                type: criteria.type,
                visibleToUsers: criteria.defaultVisible,
                criteriaMandatory: criteria.defaultMandatory,
                defaultValue: [],
                cssClass: '',
                weight: weight
            });
            instance.set(FIELD_CRITERIA, availableCriteria);
            instance.resetCriteriaWeights();
        },

        /**
         * Removes a criteria from the {{#crossLink 'SearchBoxWidgetWizard/criteria:attribute'}}{{/crossLink}} attribute
         *
         * @method _doRemoveCriteria
         * @param criteria
         * @private
         */
        _doRemoveCriteria: function (criteria) {
            var instance = this, i,
                    host = instance.get('host'),
                    editArea = host.one('.edit-criteria'),
                    availableCriteria = instance.get(FIELD_CRITERIA);

            for (i = 0; i < availableCriteria.length; i++) {
                if (criteria.type == availableCriteria[i].type) {
                    break;
                }
            }

            if (i < availableCriteria.length) {
                availableCriteria.splice(i, 1);
            }
            instance.set(FIELD_CRITERIA, availableCriteria);
            editArea.empty();
        },

        /**
         * Adds drop down events for the criteria list
         *
         * @method _addDropDownEvents
         * @private
         */
        _addDropDownEvents: function () {
            var instance = this;
            //Listen for all drop:over events
            SUBSCRIPTION_DD_OVER = Y.DD.DDM.on('drop:over', function (e) {
                //Get a reference to our drag and drop nodes
                var drag = e.drag.get('node'),
                        drop = e.drop.get('node');

                //Are we dropping on a li node?
                if (drop.hasClass('available-criteria')) {
                    //Are we not going up?
                    if (!goingUp) {
                        drop = drop.get('nextSibling');
                    }
                    //Add the node to this list
                    e.drop.get('node').get('parentNode').insertBefore(drag, drop);
                    //Resize this nodes shim, so we can drop on it later.
                    e.drop.sizeShim();
                }
            });

            //Listen for all drag:drag events
            SUBSCRIPTION_DD_DRAG = Y.DD.DDM.on('drag:drag', function (e) {
                //Get the last y point
                var y = e.target.lastXY[1];
                //is it greater than the lastY var?
                if (y < lastY) {
                    //We are going up
                    goingUp = true;
                }
                else {
                    //We are going down.
                    goingUp = false;
                }
                //Cache for next check
                lastY = y;
            });

            //Listen for all drag:start events
            SUBSCRIPTION_DD_START = Y.DD.DDM.on('drag:start', function (e) {
                //Get our drag object
                var drag = e.target;
                //Set some styles here
                drag.get('node').setStyle('opacity', '.25');
                drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
                drag.get('dragNode').setStyles({
                    opacity: '.5',
                    borderColor: drag.get('node').getStyle('borderColor'),
                    backgroundColor: drag.get('node').getStyle('backgroundColor')
                });
            });
            //Listen for a drag:end events
            SUBSCRIPTION_DD_END = Y.DD.DDM.on('drag:end', function (e) {
                var drag = e.target;
                //Put our styles back
                drag.get('node').setStyles({
                    visibility: '',
                    opacity: '1'
                });
            });
            //Listen for all drag:drophit events
            SUBSCRIPTION_DD_DROP_HIT = Y.DD.DDM.on('drag:drophit', function (e) {
                var drop = e.drop.get('node'),
                        drag = e.drag.get('node');

                //if we are not on a child, we must have been dropped on a parent
                if (drop.hasClass('criteria-list')) {
                    if (!drop.contains(drag)) {
                        drop.appendChild(drag);
                    }
                }
                instance.resetCriteriaWeights();
            });
        },


        /**
         * Resets the criteria weights
         *
         * @method resetCriteriaWeights
         * @private
         */
        resetCriteriaWeights: function () {
            var instance = this, j, i, type,
                    availableCriteria = instance.get(FIELD_CRITERIA),
                    criteriaList = Y.one('.criteria-list') ? Y.one('.criteria-list').all('.criteria-type') : [];

            for (j = 0; j < availableCriteria.length; j++) {
                for (i = 0; i < criteriaList.size(); i++) {
                    type = criteriaList.item(i).get('value');
                    if (type == availableCriteria[j].type) {
                        availableCriteria[j].weight = i;
                        break;
                    }
                }
            }
            ;
            instance.set(FIELD_CRITERIA, availableCriteria);
        }
    });

    Y.namespace('Plugin').SearchBoxWidgetWizard = SearchBoxWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'node',
        'base-build',
        'plugin',
        'classnamemanager',
        'attribute-base',
        'io-base',
        'history-hash',
        'wizardTools',
        'baseWidgetList',
        'formWidget',
        'dd-constrain',
        'dd-proxy',
        'dd-drop',
        'autocomplete',
        'datatype'
    ]
});
/**
 * This module keeps all classes used to generate elements in the widget creation wizard
 *
 * @module formWidget
 * @requires node
 */
YUI.add('formWidget', function (Y) {

    var
        /**
         * Constant field to define all reserved attributes that should not be rendered in html directly
         *
         * @property RESERVED_ATTRS
         * @type Array
         */
        RESERVED_ATTRS = ['templateList', 'destroyed', 'host', 'initialized', 'element', 'cssClass', 'wrapperCssClass', 'htmlContent', 'children', 'label', 'modelInstance', 'currentLanguage', 'disabled'],

        /**
         * Local cache to store values
         *
         * @property LOCAL_STORAGE
         * @type Object
         */
        LOCAL_STORAGE = {},

        /**
         * Template used by autocomplete class
         *
         * @property AUTOCOMPLETE_TEMPLATE
         * @type String
         */
        AUTOCOMPLETE_TEMPLATE = '<div class="result-row"><input type="hidden" value="{key}"/>{value}</div>',
        /**
         * Object used to set status of elements.
         * Can be extended in the future.
         * @type {{CHECKBOX_STATUS: string, VALUE: string, NAMESPACE: string}}
         * @static
         * @final
         */
        ELEM_ATTR = {
            CHECKBOX_STATUS: 'checked',
            VALUE: 'value',
            NAMESPACE: 'namespace'
        },
        /**
         * Object used in string replacement on function calls.
         * Can be extended in future with other attributes.
         * @type {{CHECKBOX: string, INPUT: string, RADIO: string}}
         * @static
         * @final
         */

        ELEMENT_TYPE = {
            CHECKBOX: 'CheckboxElement',
            INPUT: 'InputElement',
            RADIO: 'RadioElement'
        },
        /**
         *  Object used to set the MetaTags field types.
         *  Do not modify, MetaTags types are predefined.
         * @type {{TEXT: string, ICON: string, IMAGE: string}}
         * @static
         * @final
         */

        FIELDTYPE = {TEXT: 'TEXT', ICON: 'ICON', IMAGE: 'IMAGE'},
        METADATA_SAVED_OBJS = 'selectedMetaDataFieldType';


    if (typeof Array.prototype.contains != 'function') {
        Array.prototype.contains = function (obj) {
            var i = this.length;
            while (i--) {
                if (this[i] === obj) {
                    return true;
                }
            }
            return false;
        }
    }

    if (typeof String.prototype.startsWith != 'function') {
        // see below for better implementation!
        String.prototype.startsWith = function (str) {
            return this.indexOf(str) === 0;
        };
    }

    /**
     * Generates a basic HTML element
     *
     * @param cfg
     * @constructor
     * @class HtmlElement
     * @extends Base
     */
    var HtmlElement = function (cfg) {
        HtmlElement.superclass.constructor.apply(this, arguments);
    }
    HtmlElement.NAME = 'HtmlElement';
    HtmlElement.NS = 'HtmlElement';
    HtmlElement.ATTRS = {
        /**
         * Attribute defines the HTML title attribute
         *
         * @attribute title
         * @type String
         * @default ''
         */
        title: {
            value: ''
        },

        /**
         * Attribute defines the HTML id attribute
         *
         * @attribute id
         * @type String
         * @default ''
         */
        id: {
            value: ''
        },

        /**
         * Attribute defines the HTML name attribute
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: null
        },

        /**
         * Attribute defines the HTML value attribute, mainly used by input elements
         *
         * @attribute value
         * @type String|Array
         * @default ''
         */
        value: {
            value: null
        },

        /**
         * Attribute defines the HTML inner content
         *
         * @attribute htmlContent
         * @type String
         * @default ''
         */
        htmlContent: {
            value: ''
        },

        /**
         * Attribute defines the HTML type attribute, mainly used by input elements
         *
         * @attribute type
         * @type String
         * @default ''
         */
        type: {
            value: ''
        },

        /**
         * Attribute defines the HTML tag type
         *
         * @attribute element
         * @type String
         * @default 'div'
         */
        element: {
            value: 'div'
        },

        /**
         * Attribute defines the css classes to be added to the element
         *
         * @attribute cssClass
         * @type String
         * @default ''
         */
        cssClass: {
            value: ''
        },

        /**
         * Attribute defines the element children. This is not a direct reference to the HTML elements generated in DOM.
         * Element children can be handled using the 'host' attribute, inherited from base.
         * The following code sample will return the Node element of the first child
         *
         *      instance.get('children')[0].get('host')
         *
         * @attribute children
         * @type Array
         * @default ''
         */
        children: {
            value: []
        },

        /**
         * Keeps the callback method invoked when the onChange event fires on 'host'
         *
         * @attribute onChange
         * @type function
         * @default ''
         */
        onChange: {
            value: null
        },

        /**
         * Keeps the callback method invoked when the onClick event fires on 'host'
         *
         * @attribute onClick
         * @type function
         * @default ''
         */
        onClick: {
            value: null
        },

        /**
         * Keeps the callback method invoked when the onFocus event fires on 'host'
         *
         * @attribute onFocus
         * @type function
         * @default ''
         */
        onFocus: {
            value: null
        },

        /**
         * Keeps the callback method invoked when the onBlur event fires on 'host'
         *
         * @attribute onBlur
         * @type function
         * @default ''
         */
        onBlur: {
            value: null
        },

        /**
         * Keeps the element label. If the label is not empty, the element will be wrapped, depending on the
         * {{#crossLink 'HtmlElement/wrapWithLabel:method'}}{{/crossLink}} implementation
         *
         * @attribute label
         * @type String
         * @default ''
         */
        label: {
            value: null
        },

        /**
         * Keeps the reference to the wizard instance used as a model for this element.
         * It is used together with {{#crossLink 'HtmlElement/name:attribute'}}{{/crossLink}} attribute to
         * change the model attribute when a change event was triggered on this HTML element.
         *
         *      var instance = this,
         *          modelInstance = instance.get('modelInstance'),
         *          name = instance.get('name'),
         *          defaultValue = modelInstance.get(name);
         *
         * At this step, modelInstance will be the wizard instance that rendered this element. When this element is
         * changed, the value is automatically persisted in the attribute:
         *
         *      modelInstance.set(name, value);
         *
         * @attribute modelInstance
         * @type AbstractWizard
         * @default null
         */
        modelInstance: {
            value: null
        },

        /**
         * Attribute defines the css classes to be added to the element wrapper
         *
         * @attribute wrapperCssClass
         * @type String
         * @default null
         */
        wrapperCssClass: {
            value: null
        },

        /**
         * Keeps a list of events that this object will listen.
         *      {
         *          events: [
         *              { name: 'eventName', handler: handlerFunction }
         *          ]
         *      }
         *
         * This means that each time an eventName is fired, handlerFunction is invoked
         *
         * @attribute events
         * @type Array
         * @default []
         */
        events: { // future use
            value: [] // [{name: 'eventName', handler: handlerFunction}]
        },

        required: {
            value: false
        },

        validateFunction: {
            value: ''
        }
    };
    Y.extend(HtmlElement, Y.Base, {
        /**
         * This method initializes the object
         *
         * @method initializer
         */
        initializer: function () {
            var instance = this;
            for (var i = 0; i < instance.get('events').length; i++) {
                var descriptor = instance.get('events')[i];
                if (descriptor.handler) {
                    instance.on(descriptor.name, descriptor.handler);
                } // if a handler is not present, make the subscription in the specific object, in the overridden initializer()
            }
        },

        /**
         * Invoked by YUI when object is destroyed
         *
         * @method destructor
         */
        destructor: function () {
        },

        /**
         * Callback method triggered when the element is changed and, depending on element type, will change the attribute
         * {{#crossLink 'HtmlElement/name:attribute'}}{{/crossLink}} for the instance {{#crossLink 'HtmlElement/modelInstance:attribute'}}{{/crossLink}}
         * @param e
         * @method changeModelAttribute
         */
        changeModelAttribute: function (e) {
        },

        /**
         * Method used to generate the HTML elements in the DOM, based on each element configurations. After this method is executed,
         * a reference to the created Node element will be kept in the 'host' attribute
         *
         * @param node {Node} the YUI node that this element will use as a parent element
         * @method render
         * @return {Node}
         */
        render: function (node) {
            var instance = this,
                attrs = instance.getAttrs(),
                element = Y.Node.create('<' + instance.get('element') + '></' + instance.get('element') + '>'),
                wrapper,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                type = instance.get('type');
            instance.set('host', element);

            wrapper = instance.wrapWithLabel(element);

            if (node) {
                node.append(wrapper);
                instance.addAfterRenderEvents();
            }


            for (var property in attrs) {
                if (attrs.hasOwnProperty(property) && !RESERVED_ATTRS.contains(property) && instance.get(property)) {
                    if (property.startsWith("on")) {
                        element.on(property.substr(2, 1).toLowerCase() + property.substr(3), function (e) {
                            var eventType = e.type;

                            instance.get('on' + eventType.substr(0, 1).toUpperCase() + eventType.substr(1))(e);
                        });
                    }
                    else {
                        var propertyValue = instance.get(property);
                        if (!Y.Lang.isObject(propertyValue)) {
                            if (property.startsWith("data")) {
                                var origProperty = instance.get(property);
                                property = property.substr(0, 4) + "-" + property.substr(4, (property.length - 1));
                                element.setAttribute(property, origProperty);
                            }
                            else {
                                element.setAttribute(property, instance.get(property));
                            }
                        }
                    }
                }
            }
            if (instance.get('disabled')) {
                element.set('disabled', true);
            }
            if (instance.get('cssClass')) {
                element.addClass(instance.get('cssClass'));
            }
            if (instance.get('htmlContent')) {
                element.setHTML(instance.get('htmlContent'));
            }
            if (instance.get('children') && instance.get('children') instanceof Array) {
                for (var i = 0; i < instance.get('children').length; i++) {
                    instance.get('children')[i].render(element);
                }
            }
            if (modelInstance && name) {
                instance.setModelEvents(element);
            }
            if (instance.get('required') && instance.get('validateFunction')) {
                element.on('change', function () {
                    instance.get('validateFunction')();
                });
            }
            instance.postRender(wrapper);
            return wrapper;
        },

        /**
         * Method used to wrap elements that use label attribute
         *
         * @param elem {Node} the element to wrap
         * @method wrapWithLabel
         * @return {Node} the wrapped element or the element reference
         */
        wrapWithLabel: function (elem) {
            var instance = this,
                labelString = instance.get('label'),
                wrapperCssClass = instance.get('wrapperCssClass');
            if (!labelString && !wrapperCssClass) {
                return elem;
            }
            var wrapper = Y.Node.create('<div class="form-group"></div>');
            if (instance.get('label')) {
                var label = Y.Node.create('<label></label>');
                label.setHTML(labelString);
                label.set('for', elem.get('id'));
                wrapper.append(label);
            }
            wrapper.append(elem);

            if (wrapperCssClass) {
                wrapper.addClass(wrapperCssClass);
            }
            return wrapper;
        },

        /**
         * Set the events required by the implementation to change the model value when element value is changed
         *
         * @method setModelEvents
         * @param element {Node}
         */
        setModelEvents: function (element) {
        },

        /**
         * Adds events required after the element is rendered in DOM
         *
         * @method addAfterRenderEvents
         */
        addAfterRenderEvents: function () {
        },
        /**
         * function available to children for doing post rendering actions
         * @param elem
         * @method postRender
         */
        postRender: function (elem) {
            return elem;
        }
    });
    Y.HtmlElement = HtmlElement;

    /**
     * This class will generate a wrapper, having the label as a heading and the children in body section.
     *
     *      new PanelElement({
     *          label: 'My Panel',
     *          children: [
     *              new HtmlElement({
     *                  htmlContent: 'Hello panel!'
     *              })
     *          ]
     *      });
     *
     * will render:
     *
     *      <div class="panel panel-default">
     *          <div class="panel-heading">My Panel</div>
     *          <div class="panel-body">
     *              <div>Hello panel!</div>
     *          </div>
     *      </div>
     *
     * @param cfg
     * @constructor
     * @class PanelElement
     * @extends HtmlElement
     */
    var PanelElement = function (cfg) {
        PanelElement.superclass.constructor.apply(this, arguments);
    }
    Y.extend(PanelElement, HtmlElement, {
        wrapWithLabel: function (elem) {
            var instance = this;
            var wrapper = Y.Node.create('<div class="panel panel-default "' + 'id="' + instance.get("id") + '" style="border-color: rgba(0, 0, 0, 0.125);border-width: 0.5px;border-style: solid;"></div>');

            if (instance.get('cssClass')) {
                wrapper.addClass(instance.get('cssClass'));
            }
            if (instance.get('label')) {
                var label = Y.Node.create('<div class="panel-heading"></div>');
                label.setHTML(instance.get('label'));
                wrapper.append(label);
            }
            wrapper.append(elem);
            elem.addClass('panel-body');

            if (instance.get('wrapperCssClass')) {
                wrapper.addClass(instance.get('wrapperCssClass'));
            }
            return wrapper;
        }
    });
    Y.PanelElement = PanelElement;

    var TabPanelElement = function (cfg) {
        TabPanelElement.superclass.constructor.apply(this, arguments);
    }

    TabPanelElement.ATTRS = {
        /**
         * Attribute defines the onTabChange event for tabs
         *
         * @attribute onTabChange
         * @type Function
         * @default null
         */
        onTabChange: {
            value: null
        }
    }

    Y.extend(TabPanelElement, HtmlElement, {

        wrapWithLabel: function (elem) {
            var instance = this;
            var wrapper = Y.Node.create('<div class="widget-wizard2 sr-widget" id="sr-widget"></div>');
            var navigationList = Y.Node.create('<ul class="nav nav-tabs"></ul>');
            var activeTabStatus = "active";
            var onTabChange = instance.get('onTabChange');
            var tabNames = instance.get('label');

            if (tabNames && tabNames.length > 0) {
                for (var i = 0; i < tabNames.length; i++) {

                    var tabClass = i == 0 ? activeTabStatus : '';

                    var currentTab = Y.Node.create('<li index="#tab-' + (i + 1) + '" class="' + tabClass + '">' +
                        '<a href="#" class="' + tabClass + '">' + tabNames[i] + '</a>' +
                        '</li>');

                    var changeTab = function (currentTab, e) {

                        if (!currentTab.hasClass(activeTabStatus) && typeof onTabChange == 'function') {
                            onTabChange(e);
                        }

                        currentTab.ancestor().all("li").removeClass(activeTabStatus);
                        currentTab.addClass(activeTabStatus);

                        currentTab.ancestor().ancestor().all('.tab-content.main > .tab-pane').each(function () {
                            this.removeClass('active');
                            this.addClass('hide');
                        });

                        var activeTabNode = Y.one(e.currentTarget._node.attributes["index"].value);
                        activeTabNode.addClass('active');
                        activeTabNode.removeClass('hide');

                    };

                    if (currentTab != null) {
                        currentTab.on('click', function (e) {
                            changeTab(this, e);
                            e.preventDefault();
                        });
                        navigationList.append(currentTab);
                    }
                }
            }


            wrapper.append(navigationList);
            wrapper.append(elem);
            elem.addClass('tab-content main');

            return wrapper;
        }
    });
    Y.TabPanelElement = TabPanelElement;

    /**
     * This class will generate an input element
     *
     *      new InputElement({
     *          label: 'My input label',
     *          value: 'Hello input element!'
     *      });
     *
     * will render:
     *
     *      <div class="form-group">
     *          <label>My input label</label>
     *          <input type="text" value="Hello input element!" />
     *      </div>
     *
     * @param cfg
     * @constructor
     * @class InputElement
     * @extends HtmlElement
     */
    var InputElement = function (cfg) {
        InputElement.superclass.constructor.apply(this, arguments);
    }
    InputElement.NAME = 'InputElement';
    InputElement.NS = 'InputElement';
    InputElement.ATTRS = {
        /**
         * Defines the placeholder attribute for this input
         *
         * @attribute placeholder
         * @type {String}
         * @default ''
         */
        placeholder: {
            value: ''
        },

        /**
         * sets the type attribute value as 'text'
         *
         * @attribute type
         * @type {String}
         * @default ''
         * @readOnly
         */
        type: {
            setter: function (val, name) {
                // readOnly
            },
            value: 'text'
        },

        /**
         * sets the type attribute value as 'input'
         *
         * @attribute element
         * @type {String}
         * @default ''
         * @readOnly
         */
        element: {
            setter: function (val, name) {
                // readOnly
            },
            value: 'input'
        },

        value: {
            valule: ''
        },

        /**
         * If set to true, this element is rendered as disabled
         *
         * @attribute disabled
         * @type {Boolean}
         * @default false
         */
        disabled: {
            value: false
        }
    };
    Y.extend(InputElement, HtmlElement, {
        initializer: function () {
            var instance = this;
            instance.after("valueChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('value', e.newVal);
                }
            });
            instance.after("placeholderChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('placeholder', e.newValue);
                }
            });
        },
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                elemValue = elem.get('value');
            modelInstance.set(name, elemValue);
        },
        setModelEvents: function (element) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name');
            element.on('change', function (e) {
                instance.changeModelAttribute(e);
            });
            if (modelInstance.get(name) != undefined) {
                element.set('value', modelInstance.get(name));
            }

        }
    });
    Y.InputElement = InputElement;

    /**
     * This class will generate an slider element
     *
     *      new SliderInputElement({
     *          label: 'My slider element',
     *          value: '300'
     *      });
     *
     * will render:
     *
     *      <div class="form-group">
     *          <label>My slider element</label>
     *          <input type="text" value="300" />
     *      </div>
     *
     * @param cfg
     * @constructor
     * @class SliderInputElement
     * @extends HtmlElement
     */
    var SliderInputElement = function (cfg) {
        SliderInputElement.superclass.constructor.apply(this, arguments);
    }
    SliderInputElement.NAME = 'SliderInputElement';
    SliderInputElement.NS = 'SliderInputElement';
    SliderInputElement.ATTRS = {
        /**
         * sets the type attribute value as 'text'
         *
         * @attribute type
         * @type {String}
         * @default ''
         * @readOnly
         */
        type: {
            setter: function (val, name) {
                // readOnly
            },
            value: 'text'
        },

        value: {
            value: ''
        },

        sliderMin: {
            value: 0
        },

        sliderMax: {
            value: 100
        },

        sliderWidth: {
            value: '100 px'
        },
        /**
         * If set to true, this element is rendered as disabled
         *
         * @attribute disabled
         * @type {Boolean}
         * @default false
         */
        disabled: {
            value: false
        },

        /**
         * Instance of Y.Slide associated to input
         *
         * @attribute slider
         * @type Y.Slider
         * @default null
         */
        slider: {
            value: null
        },

        /**
         * Custom attribute to mark 'change' event as
         * an event fired from slider control
         *
         * @attribute changedBySlider
         * @type {Boolean}
         * @default false
         */
        changedBySlider: {
            value: false
        }
    };
    Y.extend(SliderInputElement, InputElement, {
        render: function (node) {
            var instance = this,
                attrs = instance.getAttrs(),
                wrapper,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                type = instance.get('type');

            var element = Y.Node.create('<input type="' + type + '"></input>');
            element.set('name', name);
            instance.set('host', element);

            var labelString = instance.get('label');
            var wrapperCssClass = instance.get('wrapperCssClass');

            wrapper = Y.Node.create('<div class="form-group slider-input"></div>');

            if (instance.get('label')) {
                var label = Y.Node.create('<label></label>');
                label.setHTML(labelString);
                label.set('for', element.get('id'));
                wrapper.append(label);
            }
            wrapper.append(element);

            var sliderHolder = Y.Node.create('<div class="slider-holder"></div>');

            var slider = new Y.Slider({
                min: instance.get('sliderMin'),
                max: instance.get('sliderMax'),
                value: instance.get('value'),
                length: instance.get('sliderWidth')
            });

            element.setData({
                slider: slider
            });

            slider.after("valueChange", function (e) {
                this.set('value', e.newVal ? e.newVal : '0');
                instance.set('changedBySlider', true);
                this.simulate('change');
                instance.set('changedBySlider', false);
            }, element);

            element.on("keyup", function (e) {
                var data = this.getData(),
                    slider = data.slider,
                    value = parseInt(this.get("value"), 10);
                if (!value) {
                    element.set('value', '0');
                }
                if (data.wait) {
                    data.wait.cancel();
                }
                data.wait = Y.later(200, slider, function () {
                    data.wait = null;
                    this.set("value", value);
                });
            });
            element.on('change', function (e) {
                if (!instance.get('changedBySlider')) {
                    var data = this.getData();
                    var slider = data.slider;
                    var value = parseInt(this.get("value"), 10);
                    if (!value) {
                        element.set('value', '0');
                    }
                    if (data.wait) {
                        data.wait.cancel();
                    }
                    data.wait = Y.later(200, slider, function () {
                        data.wait = null;
                        this.set("value", value);
                    });
                }
            });

            instance.set('slider', slider);
            slider.render(sliderHolder);
            wrapper.append(sliderHolder);
            if (wrapperCssClass) {
                wrapper.addClass(wrapperCssClass);
            }
            if (node) {
                node.append(wrapper);
                instance.addAfterRenderEvents();
            }

            for (var property in attrs) {
                if (attrs.hasOwnProperty(property) && !RESERVED_ATTRS.contains(property) && instance.get(property)) {
                    if (property.startsWith("on")) {
                        element.on(property.substr(2, 1).toLowerCase() + property.substr(3), function (e) {
                            var eventType = e.type;

                            instance.get('on' + eventType.substr(0, 1).toUpperCase() + eventType.substr(1))(e);
                        });
                    }
                    else {
                        var propertyValue = instance.get(property);
                        if (!Y.Lang.isObject(propertyValue)) {
                            if (property.startsWith("data")) {
                                var origProperty = instance.get(property);
                                property = property.substr(0, 4) + "-" + property.substr(4, (property.length - 1));
                                element.setAttribute(property, origProperty);
                            }
                            else {
                                element.setAttribute(property, instance.get(property));
                            }
                        }
                    }
                }
            }
            if (instance.get('disabled')) {
                element.set('disabled', true);
            }
            if (instance.get('cssClass')) {
                element.addClass(instance.get('cssClass'));
            }

            if (modelInstance && name) {
                instance.setModelEvents(element);
            }
            if (instance.get('required') && instance.get('validateFunction')) {
                element.on('change', function () {
                    instance.get('validateFunction')();
                });
            }
            return wrapper;
        },
        initializer: function () {
            var instance = this;
            instance.after("valueChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('value', e.newVal);
                }
            });
            instance.after("placeholderChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('placeholder', e.newValue);
                }
            });
        },
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                elemValue = elem.get('value');
            modelInstance.set(name, elemValue);
        },
        setModelEvents: function (element) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name');
            element.on('change', function (e) {
                instance.changeModelAttribute(e);
            });
            if (modelInstance.get(name) != undefined) {
                element.set('value', modelInstance.get(name));
            }

        },
        addAfterRenderEvents: function () {
            this.get('slider').syncUI();
        }
    });
    Y.SliderInputElement = SliderInputElement;

    /**
     * This class will generate an color picker input element
     *
     *      new ColorPickerInputElement({
     *          label: 'color picker',
     *          value: '#FFFFFF'
     *      });
     *
     * will render:
     *
     *      <div class="form-group color-picker-input">
     *          <label>color picker</label>
     *          <input type="text" value="#FFFFFF" />
     *      </div>
     *
     * @param cfg
     * @constructor
     * @class ColorPickerInputElement
     * @extends HtmlElement
     */
    var ColorPickerInputElement = function (cfg) {
        ColorPickerInputElement.superclass.constructor.apply(this, arguments);
    }
    ColorPickerInputElement.NAME = 'ColorPickerInputElement';
    ColorPickerInputElement.NS = 'ColorPickerInputElement';
    ColorPickerInputElement.ATTRS = {
        /**
         * sets the type attribute value as 'text'
         *
         * @attribute type
         * @type {String}
         * @default ''
         * @readOnly
         */
        type: {
            setter: function (val, name) {
                // readOnly
            },
            value: 'text'
        },

        value: {
            value: ''
        },
        /**
         * If set to true, this element is rendered as disabled
         *
         * @attribute disabled
         * @type {Boolean}
         * @default false
         */
        disabled: {
            value: false
        },

        colorPreviewBox: {
            value: null
        },

        modalButton: {
            value: null
        },
        sliderHue: {
            value: null
        },
        sliderSaturation: {
            value: null
        },
        sliderLuminance: {
            value: null
        },
        inputHue: {
            value: null
        },
        inputSaturation: {
            value: null
        },
        inputLuminance: {
            value: null
        },
        inputColorHEX: {
            value: null
        },
        inputColorRGB: {
            value: null
        },
        colorChangedByUI: {
            value: false
        }

    };
    Y.extend(ColorPickerInputElement, InputElement, {
        render: function (node) {
            var instance = this,
                attrs = instance.getAttrs(),
                wrapper,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                id = instance.get('id'),
                type = instance.get('type'),
                value = instance.get('value');

            var element = Y.Node.create('<input type="' + type + '"></input>');
            element.set('name', name ? name : (id ? id : ''));
            element.set('id', id ? id : (name ? name : ''));
            element.set('value', value ? value : '');
            instance.set('host', element);

            var labelString = instance.get('label');
            var wrapperCssClass = instance.get('wrapperCssClass');

            wrapper = Y.Node.create('<div class="form-group color-picker-input"></div>');

            if (instance.get('label')) {
                var label = Y.Node.create('<label></label>');
                label.setHTML(labelString);
                label.set('for', element.get('id'));
                wrapper.append(label);
            }

            var colorModalWrapper = Y.Node.create('<div class="color-wrapper"></div>');

            var modalButton = new Y.ButtonElement({
                id: element.get('id') + '_modal_button',
                cssClass: 'btn color-picker-button',
                value: '',
                modelInstance: instance,
                htmlContent: '',
                dataTarget: "#" + element.get('id') + "_modal_window",
                dataToggle: 'modal',
                onClick: function () {
                    instance.updatePickerUIFromValue();
                }
            });
            modalButton.render(colorModalWrapper);

            var sliderHue = new Y.Slider({min: 0, max: 360, value: 0, length: '200px'});
            var sliderSaturation = new Y.Slider({min: 0, max: 100, value: 100, length: '200px'});
            var sliderLuminance = new Y.Slider({min: 0, max: 100, value: 50, length: '200px'});

            var inputSaturation = new Y.InputElement({
                name: element.get('id') + "_saturation",
                id: element.get('id') + "_saturation",
                modelInstance: instance,
                wrapperCssClass: 'setterComponent layout-group-container',
                label: 'Saturation',
                disabled: true
            })

            var inputLuminance = new Y.InputElement({
                name: element.get('id') + "_luminance",
                id: element.get('id') + "_luminance",
                modelInstance: instance,
                wrapperCssClass: 'setterComponent layout-group-container',
                label: 'Luminance',
                disabled: true
            })

            var inputHue = new Y.InputElement({
                name: element.get('id') + "_color",
                id: element.get('id') + "_color",
                modelInstance: instance,
                wrapperCssClass: 'setterComponent layout-group-container',
                label: 'Color',
                disabled: true
            })

            var colorSetWrapper = new Y.HtmlElement({
                id: element.get('id') + "_color_box",
                cssClass: 'col-md-6 color-picker-col-edit',
                children: [
                    new Y.HtmlElement({
                        id: element.get('id') + "_color_box_sat",
                        cssClass: 'col-md-12',
                        children: [inputSaturation, sliderSaturation]
                    }),

                    new Y.HtmlElement({
                        id: element.get('id') + "_color_box_lum",
                        cssClass: 'col-md-12',
                        children: [inputLuminance, sliderLuminance]
                    }),

                    new Y.HtmlElement({
                        id: element.get('id') + "_color_box_color",
                        cssClass: 'col-md-12 modal_color_box_color',
                        children: [inputHue, sliderHue]
                    })
                ]
            })

            var colorPreview = new Y.HtmlElement({
                id: element.get('id') + "_color_box_view_color",
                cssClass: 'colorPicker-preview clearfix'
            })

            var inputColorRGB = new Y.InputElement({
                name: element.get('id') + "_color_rgb",
                id: element.get('id') + "_color_rgb",
                modelInstance: instance,
                wrapperCssClass: 'col-md-12 layout-group-container',
                label: 'RGB',
                disabled: true
            })

            var inputColorHEX = new Y.InputElement({
                name: element.get('id') + "_color_hex",
                id: element.get('id') + "_color_hex",
                modelInstance: instance,
                wrapperCssClass: 'col-md-12 layout-group-container',
                label: 'HEX',
                disabled: true
            })

            var colorPreviewWrapper = new Y.HtmlElement({
                cssClass: 'col-md-6 color-picker-col-preview',
                children: [
                    colorPreview,
                    inputColorRGB,
                    inputColorHEX
                ]
            })

            var modalWindow = new Y.HtmlElement({
                id: element.get('id') + "_modal_window",
                cssClass: "modal fade color-picker-modal",
                children: [
                    new Y.HtmlElement({
                        cssClass: 'modal-dialog',
                        children: [
                            new Y.HtmlElement({
                                cssClass: 'modal-content',
                                children: [
                                    new Y.HtmlElement({
                                        cssClass: 'modal-header',
                                        children: []
                                    }),
                                    new Y.HtmlElement({
                                        cssClass: 'modal-body',
                                        children: [
                                            new Y.HtmlElement({
                                                cssClass: 'dialer-content',
                                                children: [
                                                    colorSetWrapper,
                                                    colorPreviewWrapper
                                                ]
                                            })
                                        ]
                                    }),
                                    new Y.HtmlElement({
                                        cssClass: 'modal-footer',
                                        children: [
                                            new Y.ButtonElement({
                                                cssClass: 'btn btn-default',
                                                dataDismiss: 'modal',
                                                htmlContent: "Close"
                                            })
                                        ]
                                    })
                                ]
                            })
                        ]
                    })
                ]
            });

            sliderSaturation.after('valueChange', function (e) {
                instance.updatePickerUI();
            });

            sliderHue.after('valueChange', function (e) {
                instance.updatePickerUI();
            });

            sliderLuminance.after('valueChange', function (e) {
                instance.updatePickerUI();
            });

            element.on('change', function (e) {
                if (!instance.get('colorChangedByUI')) {
                    instance.updatePickerUIFromValue();
                }
            });

            modalWindow.render(colorModalWrapper);

            wrapper.append(colorModalWrapper);
            wrapper.append(element);

            if (wrapperCssClass) {
                wrapper.addClass(wrapperCssClass);
            }
            if (node) {
                node.append(wrapper);
                instance.addAfterRenderEvents();
            }

            for (var property in attrs) {
                if (attrs.hasOwnProperty(property) && !RESERVED_ATTRS.contains(property) && instance.get(property)) {
                    if (property.startsWith("on")) {
                        element.on(property.substr(2, 1).toLowerCase() + property.substr(3), function (e) {
                            var eventType = e.type;

                            instance.get('on' + eventType.substr(0, 1).toUpperCase() + eventType.substr(1))(e);
                        });
                    }
                    else {
                        var propertyValue = instance.get(property);
                        if (!Y.Lang.isObject(propertyValue)) {
                            if (property.startsWith("data")) {
                                var origProperty = instance.get(property);
                                property = property.substr(0, 4) + "-" + property.substr(4, (property.length - 1));
                                element.setAttribute(property, origProperty);
                            }
                            else {
                                element.setAttribute(property, instance.get(property));
                            }
                        }
                    }
                }
            }
            if (instance.get('disabled')) {
                element.set('disabled', true);
            }
            if (instance.get('cssClass')) {
                element.addClass(instance.get('cssClass'));
            }

            if (modelInstance && name) {
                instance.setModelEvents(element);
            }
            if (instance.get('required') && instance.get('validateFunction')) {
                element.on('change', function () {
                    instance.get('validateFunction')();
                });
            }
            instance.set('colorPreviewBox', colorPreview);
            instance.set('modalButton', modalButton);

            instance.set('sliderHue', sliderHue);
            instance.set('sliderSaturation', sliderSaturation);
            instance.set('sliderLuminance', sliderLuminance);

            instance.set('inputHue', inputHue);
            instance.set('inputSaturation', inputSaturation);
            instance.set('inputLuminance', inputLuminance);
            instance.set('inputColorHEX', inputColorHEX);
            instance.set('inputColorRGB', inputColorRGB);

            instance.updatePickerUIFromValue();
            return wrapper;
        },
        updatePickerUI: function () {
            var instance = this,
                host = instance.get('host'),
                sliderHue = instance.get('sliderHue'),
                sliderSaturation = instance.get('sliderSaturation'),
                sliderLuminance = instance.get('sliderLuminance'),
                colorPreviewBox = instance.get('colorPreviewBox'),
                modalButton = instance.get('modalButton'),
                inputHue = instance.get('inputHue'),
                inputSaturation = instance.get('inputSaturation'),
                inputLuminance = instance.get('inputLuminance'),
                inputColorHEX = instance.get('inputColorHEX'),
                inputColorRGB = instance.get('inputColorRGB'),
                sliderHue = instance.get('sliderHue'),
                sliderHue = instance.get('sliderHue');


            var h = sliderHue.get('value'),
                s = sliderSaturation.get('value'),
                l = sliderLuminance.get('value'),
                hslString = Y.Color.fromArray([h, s, l], Y.Color.TYPES.HSL),
                hexString = Y.Color.toHex(hslString),
                rgbString = Y.Color.toRGB(hslString);

            var colorPreviewNode = Y.one('#' + colorPreviewBox.get('id'));
            var modalButtonNode = Y.one('#' + modalButton.get('id'));

            if (colorPreviewNode) {
                colorPreviewNode.setStyle('backgroundColor', hexString);
            }
            if (modalButtonNode) {
                modalButtonNode.setStyle('backgroundColor', hexString);
            }

            inputHue.set('value', h);
            inputSaturation.set('value', s);
            inputLuminance.set('value', l);

            inputColorHEX.set('value', hexString);
            inputColorRGB.set('value', rgbString);
            instance.set('value', hexString);
            host.set('value', hexString);

            instance.set('colorChangedByUI', true);
            host.simulate('change');
            instance.set('colorChangedByUI', false);
        },
        updatePickerUIFromValue: function () {
            var instance = this,
                host = instance.get('host'),
                sliderHue = instance.get('sliderHue'),
                sliderSaturation = instance.get('sliderSaturation'),
                sliderLuminance = instance.get('sliderLuminance'),
                colorPreviewBox = instance.get('colorPreviewBox'),
                modalButton = instance.get('modalButton'),
                inputHue = instance.get('inputHue'),
                inputSaturation = instance.get('inputSaturation'),
                inputLuminance = instance.get('inputLuminance'),
                inputColorHEX = instance.get('inputColorHEX'),
                inputColorRGB = instance.get('inputColorRGB');

            var hexColor = host.get('value').replace('#', '');

            var hslString = Y.Color.toHSL(hexColor);
            var rgbString = Y.Color.toRGB(hexColor);
            var hslArray = Y.Color.toArray(hslString);

            if (hslArray && hslArray.length >= 3) {
                sliderHue.set('value', hslArray[0]);
                sliderSaturation.set('value', hslArray[1]);
                sliderLuminance.set('value', hslArray[2]);
            }
            var colorPreviewNode = colorPreviewBox.get('host');
            var modalButtonNode = modalButton.get('host');

            if (colorPreviewNode) {
                colorPreviewNode.set('style', 'background-color: #' + hexColor);
            }
            if (modalButtonNode) {
                modalButtonNode.set('style', 'background-color: #' + hexColor);
            }

            inputColorHEX.set('value', '#' + hexColor);
            inputColorRGB.set('value', rgbString);

            instance.set('value', '#' + hexColor);
            host.set('value', '#' + hexColor);
        },
        initializer: function () {
            var instance = this;
            instance.after("valueChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('value', e.newVal);
                }
            });
            instance.after("placeholderChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('placeholder', e.newValue);
                }
            });
        },
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                elemValue = elem.get('value');
            modelInstance.set(name, elemValue);
        },
        setModelEvents: function (element) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name');
            element.on('change', function (e) {
                instance.changeModelAttribute(e);
            });
            if (modelInstance.get(name) != undefined) {
                element.set('value', modelInstance.get(name));
            }

        },
        addAfterRenderEvents: function () {
        }
    });
    Y.ColorPickerInputElement = ColorPickerInputElement;

    var ButtonElement = function (cfg) {
        ButtonElement.superclass.constructor.apply(this, arguments);
    }
    ButtonElement.NAME = 'ButtonElement';
    ButtonElement.NS = 'ButtonElement';
    ButtonElement.ATTRS = {
        /**
         * Defines the placeholder attribute for this input
         *
         * @attribute placeholder
         * @type {String}
         * @default ''
         */
        placeholder: {
            value: ''
        },

        /**
         * sets the type attribute value as 'text'
         *
         * @attribute type
         * @type {String}
         * @default ''
         * @readOnly
         */
        type: {
            setter: function (val, name) {
                // readOnly
            },
            value: 'text'
        },

        /**
         * sets the type attribute value as 'input'
         *
         * @attribute element
         * @type {String}
         * @default ''
         * @readOnly
         */
        element: {
            setter: function (val, name) {
                // readOnly
            },
            value: 'button'
        },

        value: {
            valule: ''
        },

        /**
         * If set to true, this element is rendered as disabled
         *
         * @attribute disabled
         * @type {Boolean}
         * @default false
         */
        disabled: {
            value: false
        },

        dataTarget: {
            value: ''
        },

        dataToggle: {
            value: ''
        },
        dataDismiss: {
            value: ''
        }

    };
    Y.extend(ButtonElement, HtmlElement, {
        initializer: function () {
            var instance = this;
            var host = instance.get('host');

            //if(instance.get("dataTarget").length > 0 && host) {
            //    host.setAttribute('data-target', instance.get("dataTarget"));
            //
            //}
            //if(instance.get("dataToggle").length > 0 && host) {
            //    host.setAttribute('dataToggle', instance.get("dataToggle"));
            //}

            instance.after("valueChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('value', e.newVal);
                }
            });
            instance.after("placeholderChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('placeholder', e.newValue);
                }
            });
        },
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                elemValue = elem.get('value');
            modelInstance.set(name, elemValue);
        },
        setModelEvents: function (element) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name');
            element.on('change', function (e) {
                instance.changeModelAttribute(e);
            });
            if (modelInstance.get(name) != undefined) {
                element.set('value', modelInstance.get(name));
            }

        }
    });
    Y.ButtonElement = ButtonElement;


    /**
     * This class will generate a checkbox element
     *
     *      new CheckboxElement({
     *          label: 'My checkbox label',
     *          value: 'Hello checkbox!'
     *      });
     *
     * will render:
     *
     *      <div class="checkbox">
     *          <label><input type="checkbox" value="Hello checkbox!" /> My checkbox label</label>
     *      </div>
     *
     * @param cfg
     * @constructor
     * @class CheckboxElement
     * @extends InputElement
     */
    var CheckboxElement = function (cfg) {
        CheckboxElement.superclass.constructor.apply(this, arguments);

    };
    CheckboxElement.NAME = 'CheckboxElement';
    CheckboxElement.NS = 'CheckboxElement';
    CheckboxElement.ATTRS = {
        /**
         * @attribute type
         * @type String
         * @readOnly
         * @default checkbox
         */
        type: {
            readOnly: true,
            value: 'checkbox'
        },

        /**
         * if is set to true, the element will be rendered as checked. This value is overridden by modelInstance functionality
         * @attribute checked
         * @type String
         * @default ''
         */
        checked: {
            value: ''
        }
    };
    Y.extend(CheckboxElement, InputElement, {
        wrapWithLabel: function (elem) {
            var instance = this, labelText = instance.get('label'),
                label, wrapper;
            if (!labelText) {
                return elem;
            }

            label = Y.Node.create('<label></label>');
            label.append(elem);
            label.append(labelText);
            wrapper = Y.Node.create('<div class="' + instance.get('type') + '"></div>');
            wrapper.append(label);

            if (instance.get('wrapperCssClass')) {
                wrapper.addClass(instance.get('wrapperCssClass'));
            }
            return wrapper;
        },
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                value = '',
                elemValue = elem.get('defaultValue');

            if (elem.get('checked') || elem.get('selected')) {
                if (Y.Array.indexOf(modelInstance.get(name), elemValue) < 0) {
                    value = modelInstance.get(name);
                    value.push(elemValue);
                }
            }
            else if (Y.Array.indexOf(modelInstance.get(name), elemValue) >= 0) {
                value = Y.Array.filter(modelInstance.get(name), function (item) {
                    return item != elemValue;
                });
            }
            else {
                value = modelInstance.get(name);
            }
            if (!value) {
                value = [];
            }
            modelInstance.set(name, value);
        },
        setModelEvents: function (element) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name');
            element.on('change', function (e) {
                instance.changeModelAttribute(e);
            });
            if (Y.Array.indexOf(modelInstance.get(name), instance.get('value')) >= 0) {
                element.set('checked', true);
            }
        }
    });
    Y.CheckboxElement = CheckboxElement;

    /**
     * This class will generate a checkbox with options element
     *     *
     * @param cfg
     * @constructor
     * @class CheckboxWithOptionsElement
     * @extends CheckboxElement
     */
    var CheckboxWithOptionsElement = function (cfg) {
        CheckboxWithOptionsElement.superclass.constructor.apply(this, arguments);

    };
    CheckboxWithOptionsElement.NAME = 'CheckboxWithOptionsElement';
    CheckboxWithOptionsElement.NS = 'CheckboxWithOptionsElement';
    CheckboxWithOptionsElement.ATTRS = {
        /**
         * @attribute type
         * @type String
         * @readOnly
         * @default checkbox
         */
        type: {
            readOnly: true,
            value: 'checkbox'
        },

        /**
         * if is set to true, the element will be rendered as checked. This value is overridden by modelInstance functionality
         * @attribute checked
         * @type String
         * @default ''
         */
        checked: {
            value: ''
        },

        optionsArrayField: {
            value: ''
        },
        optionsArray: {
            value: []
        },
        subOptionsArrayField: {
            value: ''
        }
    };
    Y.extend(CheckboxWithOptionsElement, CheckboxElement, {
        wrapWithLabel: function (elem) {
            var instance = this,
                labelText = instance.get('label'),
                optionsArray = instance.get('optionsArray');

            if (!labelText) {
                return elem;
            }

            var wrapper = Y.Node.create('<div class="' + ' checkbox-with-options ' + instance.get('type') + '"></div>');

            if (labelText) {
                var label = Y.Node.create('<label></label>');
                label.append(labelText);
                label.append(elem);
                wrapper.append(label);
            }
            else {
                wrapper.append(elem);
            }

            if (optionsArray) {
                var iconSelect = Y.Node.create('<span class="icon-chevron-down"></span>');
                iconSelect.on('click', function (e) {
                    instance.openOptionsMenu(this);
                });
                wrapper.append(iconSelect);
            }

            if (instance.get('wrapperCssClass')) {
                wrapper.addClass(instance.get('wrapperCssClass'));
            }
            return wrapper;
        },
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                value = '',
                elemValue = elem.get('defaultValue');

            if (elem.get('checked') || elem.get('selected')) {
                if (Y.Array.indexOf(modelInstance.get(name), elemValue) < 0) {
                    value = modelInstance.get(name);
                    value.push(elemValue);
                }
            }
            else if (Y.Array.indexOf(modelInstance.get(name), elemValue) >= 0) {
                value = Y.Array.filter(modelInstance.get(name), function (item) {
                    return item != elemValue;
                });
            }
            else {
                value = modelInstance.get(name);
            }
            if (!value) {
                value = [];
            }
            modelInstance.set(name, value);
        },
        setModelEvents: function (element) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name');
            element.on('change', function (e) {
                instance.changeModelAttribute(e);
            });
            if (Y.Array.indexOf(modelInstance.get(name), instance.get('value')) >= 0) {
                element.set('checked', true);
            }
        },

        openOptionsMenu: function (targetElement) {
            var instance = this,
                popover = instance.get('popover'),
                modelInstance = instance.get('modelInstance'),
                optionsArray = instance.get('optionsArray'),
                optionsArrayField = instance.get('optionsArrayField'),
                savedOptions = modelInstance.get(optionsArrayField);

            if (!optionsArray) {
                return;
            }
            if (!popover) {

                if (!Y.Lang.isArray(savedOptions)) {
                    savedOptions = [];
                }

                var popoverContent = '<div class="popoverContent"><ul>';
                for (var i = 0; i < optionsArray.length; i++) {
                    if (modelInstance.get("widgetType") == 3 && optionsArray[i].key == "relevance") {
                        continue;
                    }
                    popoverContent += '<li>';
                    popoverContent += '<input type="checkbox"' +
                        ' name="' + instance.get('name') + '_options"' +
                        ' value="' + optionsArray[i].key + '" ' +
                        (Y.Array.indexOf(savedOptions, optionsArray[i].key) > -1 ? ' checked' : '') + ' />';
                    var subOptionsLabel = '';
                    if (optionsArray[i].options) {
                        subOptionsLabel = '<span class="icon-chevron-down" id="' + instance.get('namespace') + optionsArray[i].key + '_FilterTopics"></span>';
                    }
                    popoverContent += '<span class="option-label">' + optionsArray[i].label + '</span>' + subOptionsLabel;
                    popoverContent += '</li>';

                }
                popoverContent += '</ul></div>';

                popover = new Y.Popover({
                    align: {
                        node: targetElement,
                        points: [Y.WidgetPositionAlign.TC, Y.WidgetPositionAlign.BC]
                    },
                    bodyContent: popoverContent,
                    position: 'bottom'
                }).render();
                var popoverNode = popover ? popover.get('srcNode') : undefined;
                if (popoverNode) {
                    popoverNode.get('parentNode').setStyle('z-index', '');
                    popoverNode.all('input[name="' + instance.get('name') + '_options"]').each(function (checkbox) {
                        checkbox.on('change', function (e) {
                            instance.modifyOptions(e.target);
                        });
                    });
                }
                instance.set('popover', popover);

                //open sub subOptions popover
                for (var optionIndex = 0; optionIndex < optionsArray.length; optionIndex++) {
                    if (optionsArray[optionIndex].options) {
                        var optionsPopOver = popoverNode.one('#' + instance.get('namespace') + optionsArray[optionIndex].key + '_FilterTopics');
                        var crtOption = optionsArray[optionIndex];
                        optionsPopOver.on('click', function (e) {
                            if (crtOption.key==='custom'){
                                instance.openCustomSubOptionsMenu(crtOption, optionsPopOver, instance);
                            } else {
                                instance.openSubOptionsMenu(crtOption, optionsPopOver, instance);
                            }
                        });

                    }
                }

            }
            else {
                popover.set('visible', !popover.get('visible'));
                if (!popover.get('visible')) {
                    //hide child popovers
                    var childPopovers = instance.get('subOptionsPopover');
                    for (var childPopover in childPopovers) {
                        if (childPopovers.hasOwnProperty(childPopover)) {
                            childPopovers[childPopover].set('visible', false);
                        }
                    }
                }
            }
        },

        openSubOptionsMenu: function (option, popoverButton, instance) {
            if (!instance.get('subOptionsPopover')) {
                instance.set('subOptionsPopover', {});
            }

            var optionPopover = instance.get('subOptionsPopover')[option.key];
            if (!optionPopover) {
                var popoverContent = '<div class="popoverContent optionsPopoverContent"><ul>';
                for (var i = 0; i < option.options.length; i++) {

                    popoverContent += '<li>';
                    var checked = '';
                    if (instance.isSubOptionChecked(instance, option.options[i].id, option.key)) {
                        checked = 'checked';
                    }
                    popoverContent += '<input type="checkbox"' +
                        ' name="' + instance.get('name') + option.key + '_options"' +
                        ' value="' + option.options[i].id + '" ' +
                        checked +
                        ' />';
                    popoverContent += '<span class="sub-option-label">' + option.options[i].name + '</span>';
                    popoverContent += '</li>';

                }
                popoverContent += '</ul></div>';

                optionPopover = new Y.Popover({
                    align: {
                        node: popoverButton,
                        points: [Y.WidgetPositionAlign.TC, Y.WidgetPositionAlign.BC]
                    },
                    bodyContent: popoverContent,
                    position: 'bottom'
                }).render();
                //save the popover
                instance.get('subOptionsPopover')[option.key] = optionPopover;

                var optionPopoverNode = optionPopover ? optionPopover.get('srcNode') : undefined;
                if (optionPopoverNode) {
                    optionPopoverNode.get('parentNode').setStyle('z-index', '');
                    var optionKey = option.key;
                    optionPopoverNode.all('input[name="' + instance.get('name') + option.key + '_options"]').each(function (checkbox) {
                        checkbox.on('change', function (e) {
                            instance.modifySubOptions(e.target, optionKey);
                        });
                    });
                }
            }
            else {
                optionPopover.set('visible', !optionPopover.get('visible'));
            }
        },

        openCustomSubOptionsMenu: function (option, popoverButton, instance) {
            var modelInstance = instance.get('modelInstance');
            if (!instance.get('subOptionsPopover')) {
                instance.set('subOptionsPopover', {});
            }

            var optionPopover = instance.get('subOptionsPopover')[option.key];
            if (!optionPopover) {
                var popoverContent = '<div class="row widget-template-add">';
                popoverContent += '<div class="col col-md-3"><span class="widget-template-add-label pull-right">' + modelInstance.t('baseWidgetList.templates.new') + '</span></div>';
                popoverContent += '<div class="col col-md-9">' +
                    '<div class="input-group">' +
                    '<input type="text" id="newCustomName" class="form-control widget-template-name-input" placeholder="' + modelInstance.t('baseWidgetList.templates.saveCustom') + '">' +
                    '<div class="input-group-append">' +
                    '<button id="saveNewCustom" class="widget-template-add-button btn btn-primary" type="button"><i class="icon-check"></i></button>' +
                    '</div>' +
                    '</div>' +
                    '</div>';
                popoverContent += '</div>';
                popoverContent += '<div id="customPopoverContent" class="popoverContent optionsPopoverContent"><ul class="custom-widget-filter-topic">';
                for (var i = 0; i < option.options.length; i++) {

                    popoverContent += '<li>';
                    popoverContent += '<span class="sub-option-label">' + option.options[i].name + '</span>';
                    popoverContent += '<span class="template-controls">';
                    popoverContent += '<i class="icon-remove remove-template" title="' + modelInstance.t('baseWidgetList.templates.removeCustom') + '" templateId="' + option.options[i].name + '" ></i>';
                    popoverContent += '<i class="icon-arrow-up move-up-template" title="' + modelInstance.t('baseWidgetList.templates.moveCustom') + '" templateId="' + option.options[i].name + '" ></i>';
                    popoverContent += '<i class="icon-arrow-down move-down-template" title="' + modelInstance.t('baseWidgetList.templates.moveDownCustom') + '" templateId="' + option.options[i].name + '" ></i>';
                    popoverContent += '</span>';
                    popoverContent += '</li>';

                }
                popoverContent += '</ul></div>';

                optionPopover = new Y.Popover({
                    align: {
                        node: popoverButton,
                        points: [Y.WidgetPositionAlign.TC, Y.WidgetPositionAlign.BC]
                    },
                    bodyContent: popoverContent,
                    position: 'bottom'
                }).render();
                //save the popover
                instance.get('subOptionsPopover')[option.key] = optionPopover;

                var optionPopoverNode = optionPopover ? optionPopover.get('srcNode') : undefined;
                if (optionPopoverNode) {
                    optionPopoverNode.get('parentNode').setStyle('z-index', '');
                    var optionKey = option.key;
                }


                var saveNewCustomBtn = Y.one("#saveNewCustom");
                saveNewCustomBtn.on('click', function (e) {
                    var customNameBox = Y.one('#newCustomName');
                    var newCustomName = customNameBox.get('value');
                    var customPopoverContent = Y.one('#customPopoverContent');
                    customPopoverContent.one('ul').append('<li><span class="sub-option-label">'+newCustomName+'</span><span class="template-controls">' +
                        '<i class="icon-remove remove-template" title="' + modelInstance.t('baseWidgetList.templates.removeCustom') + '" templateId="' + newCustomName + '" ></i>' +
                        '<i class="icon-arrow-up move-up-template" title="' + modelInstance.t('baseWidgetList.templates.moveCustom') + '" templateId="' + newCustomName + '" ></i>'+
                        '<i class="icon-arrow-down move-down-template" title="' + modelInstance.t('baseWidgetList.templates.moveDownCustom') + '" templateId="' + newCustomName + '" ></i></span></li>');
                    instance.modifyCustomSubOptions(optionKey, newCustomName);
                });

                var attachTemplateEvents = function (templateNode) {
                    templateNode.all(".remove-template").on('click', function (e) {
                        var templateId = e.target.getAttribute('templateId');
                        var liNode = e.target.ancestor('li');
                        instance.removeCustomSubOptions(optionKey, templateId);
                        liNode.remove();
                    });

                    templateNode.all(".move-up-template").on('click', function (e) {
                        var templateId = e.target.getAttribute('templateId');
                        // var liNode = e.target.ancestor('li');
                        var currentIndex = instance.getIdexOfSubOptions(optionKey, templateId);
                        if (currentIndex>0){
                            instance.moveUpCustomSubOptions(optionKey, templateId);
                            $('.custom-widget-filter-topic li:eq('+(currentIndex-1)+')').before($('.custom-widget-filter-topic li:eq('+currentIndex+')'))
                        }
                    });

                    templateNode.all(".move-down-template").on('click', function (e) {
                        var templateId = e.target.getAttribute('templateId');
                        var currentIndex = instance.getIdexOfSubOptions(optionKey, templateId);
                        if (!instance.isLastIndex(optionKey, templateId)) {
                            instance.moveDownCustomSubOptions(optionKey, templateId);
                            $('.custom-widget-filter-topic li:eq(' + (currentIndex) + ')').before($('.custom-widget-filter-topic li:eq(' + (currentIndex + 1) + ')'))
                        }
                    });

                };

                Y.all('.optionsPopoverContent .custom-widget-filter-topic li').each(function (templateNode) {
                    attachTemplateEvents(templateNode);
                });

            }
            else {
                optionPopover.set('visible', !optionPopover.get('visible'));
            }
        },

        getIdexOfSubOptions: function (optionKey, newKey) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                subOptionsField = instance.get('subOptionsArrayField'),
                subOptionsObject = modelInstance.get(subOptionsField);

            var subOptionsObjectValues = subOptionsObject[optionKey];
            if (!subOptionsObjectValues) {
                subOptionsObjectValues = [];
            }
            var currentValueIndex = Y.Array.indexOf(subOptionsObjectValues, newKey);
            return currentValueIndex;
        },

        isLastIndex: function (optionKey, newKey) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                subOptionsField = instance.get('subOptionsArrayField'),
                subOptionsObject = modelInstance.get(subOptionsField);

            var subOptionsObjectValues = subOptionsObject[optionKey];
            if (!subOptionsObjectValues) {
                subOptionsObjectValues = [];
            }
            var currentValueIndex = Y.Array.indexOf(subOptionsObjectValues, newKey);
            return currentValueIndex === subOptionsObjectValues.length;
        },

        isSubOptionChecked: function (instance, subOptionValue, optionKey) {
            var modelInstance = instance.get('modelInstance'),
                subOptionsField = instance.get('subOptionsArrayField'),
                subOptionsObject = modelInstance.get(subOptionsField);
            var subOptionsObjectValues = subOptionsObject[optionKey];
            if (!subOptionsObjectValues) {
                return false;
            }
            var currentValueIndex = Y.Array.indexOf(subOptionsObjectValues, subOptionValue);
            return currentValueIndex >= 0;
        },

        modifyCustomSubOptions: function (optionKey, newKey) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                subOptionsField = instance.get('subOptionsArrayField'),
                subOptionsObject = modelInstance.get(subOptionsField);

            var subOptionsObjectValues = subOptionsObject[optionKey];
            if (!subOptionsObjectValues) {
                subOptionsObjectValues = [];
            }
            var currentValueIndex = Y.Array.indexOf(subOptionsObjectValues, newKey);
            if (currentValueIndex > -1) {
                return;
            }
            subOptionsObjectValues.push(newKey);
            subOptionsObject[optionKey] = subOptionsObjectValues;
            modelInstance.set(subOptionsField, subOptionsObject);
        },

        removeCustomSubOptions: function (optionKey, newKey) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                subOptionsField = instance.get('subOptionsArrayField'),
                subOptionsObject = modelInstance.get(subOptionsField);

            var subOptionsObjectValues = subOptionsObject[optionKey];
            if (!subOptionsObjectValues) {
                subOptionsObjectValues = [];
            }
            var currentValueIndex = Y.Array.indexOf(subOptionsObjectValues, newKey);
            if (currentValueIndex > -1) {
                subOptionsObjectValues.splice(currentValueIndex, 1);
            }
            subOptionsObject[optionKey] = subOptionsObjectValues;
            modelInstance.set(subOptionsField, subOptionsObject);
        },

        moveUpCustomSubOptions: function (optionKey, newKey) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                subOptionsField = instance.get('subOptionsArrayField'),
                subOptionsObject = modelInstance.get(subOptionsField);

            var subOptionsObjectValues = subOptionsObject[optionKey];
            if (!subOptionsObjectValues) {
                subOptionsObjectValues = [];
            }
            var currentValueIndex = Y.Array.indexOf(subOptionsObjectValues, newKey);
            if (currentValueIndex > 0) {
                subOptionsObjectValues.splice(currentValueIndex-1, 0, subOptionsObjectValues.splice(currentValueIndex, 1)[0]);
            }
            subOptionsObject[optionKey] = subOptionsObjectValues;
            modelInstance.set(subOptionsField, subOptionsObject);
        },

        moveDownCustomSubOptions: function (optionKey, newKey) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                subOptionsField = instance.get('subOptionsArrayField'),
                subOptionsObject = modelInstance.get(subOptionsField);

            var subOptionsObjectValues = subOptionsObject[optionKey];
            if (!subOptionsObjectValues) {
                subOptionsObjectValues = [];
            }
            var currentValueIndex = Y.Array.indexOf(subOptionsObjectValues, newKey);
            if (currentValueIndex < subOptionsObjectValues.length - 1) {
                subOptionsObjectValues.splice(currentValueIndex, 0, subOptionsObjectValues.splice(currentValueIndex + 1, 1)[0]);
            }
            subOptionsObject[optionKey] = subOptionsObjectValues;
            modelInstance.set(subOptionsField, subOptionsObject);
        },


        modifySubOptions: function (checkbox, optionKey) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                subOptionsField = instance.get('subOptionsArrayField'),
                subOptionsObject = modelInstance.get(subOptionsField);

            var subOptionsObjectValues = subOptionsObject[optionKey];
            if (!subOptionsObjectValues) {
                subOptionsObjectValues = [];
            }
            var checked = checkbox.get('checked');
            var checkboxValue = checkbox.get('value');

            var currentValueIndex = Y.Array.indexOf(subOptionsObjectValues, checkboxValue);
            if (checked) {
                if (currentValueIndex > -1) {
                    return;
                }
                subOptionsObjectValues.push(checkboxValue);
            }
            else {
                if (currentValueIndex == -1) {
                    return;
                }
                subOptionsObjectValues.splice(currentValueIndex, 1);
            }
            subOptionsObject[optionKey] = subOptionsObjectValues;
            if (subOptionsObjectValues.length > 0) {
                var popover = instance.get('popover')
                var popoverNode = popover ? popover.get('srcNode') : undefined;
                if (popoverNode) {
                    popoverNode.all('input[name="' + instance.get('name') + '_options"]').each(function (checkbox) {
                        if (checkbox.get('value') === optionKey) {
                            checkbox.set('checked', true);
                        }
                    });
                }
            }
            modelInstance.set(subOptionsField, subOptionsObject);
        },
        modifyOptions: function (checkbox) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                optionsArrayField = instance.get('optionsArrayField'),
                checkboxOptionsValues = modelInstance.get(optionsArrayField);

            var checked = checkbox.get('checked');
            var checkboxValue = checkbox.get('value');

            if (!Y.Lang.isArray(checkboxOptionsValues)) {
                checkboxOptionsValues = [];
            }
            var currentValueIndex = Y.Array.indexOf(checkboxOptionsValues, checkboxValue);
            if (checked) {
                if (currentValueIndex > -1) {
                    return;
                }
                checkboxOptionsValues.push(checkboxValue);
            }
            else {
                if (currentValueIndex == -1) {
                    return;
                }
                checkboxOptionsValues.splice(currentValueIndex, 1);
            }

            modelInstance.set(optionsArrayField, checkboxOptionsValues);

        }
    });
    Y.CheckboxWithOptionsElement = CheckboxWithOptionsElement;

    /**
     * This class will generate a radio element
     *
     *      new RadioElement({
     *          label: 'My radio label',
     *          value: 'Hello radio!'
     *      });
     *
     * will render:
     *
     *      <div class="radio">
     *          <label><input type="radio" value="Hello radio!" /> My radio label</label>
     *      </div>
     *
     * @param cfg
     * @constructor
     * @class RadioElement
     * @extends CheckboxElement
     */
    var RadioElement = function (cfg) {
        RadioElement.superclass.constructor.apply(this, arguments);
    }
    RadioElement.NAME = 'RadioElement';
    RadioElement.NS = 'RadioElement';
    RadioElement.ATTRS = {
        /**
         * @attribute type
         * @type String
         * @readOnly
         * @default radio
         */
        type: {
            readOnly: true,
            value: 'radio'
        }
    };
    Y.extend(RadioElement, CheckboxElement, {
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                value = '',
                elemValue = elem.get('defaultValue');

            if (elem.get('checked') || elem.get('selected')) {
                value = elemValue;
            }
            else {
                value = '';
            }
            modelInstance.set(name, value);
        },
        setModelEvents: function (element) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                value = modelInstance.get(name);
            element.on('change', function (e) {
                instance.changeModelAttribute(e);
            });
            if ((Y.Lang.isArray(value) && Y.Array.indexOf(modelInstance.get(name), instance.get('value')) >= 0)
                || value === instance.get('value')) {
                element.set('checked', true);
            }
        }
    });
    Y.RadioElement = RadioElement;

    /**
     * This class will generate an option element
     *
     * @param cfg
     * @constructor
     * @class OptionElement
     * @extends HtmlElement
     */
    var OptionElement = function (cfg) {
        OptionElement.superclass.constructor.apply(this, arguments);
    };
    OptionElement.ATTRS = {
        /**
         * @readOnly
         * @attribute element
         * @default 'option'
         */
        element: {
            setter: function (val, name) {
                // readOnly
            },
            value: 'option'
        },
        /**
         * Attribute that states if this option element is selected or not
         * @attribute selected
         * @type {Boolean}
         * @default false
         */
        selected: {
            value: false
        }
    };
    Y.extend(OptionElement, HtmlElement, {});
    Y.OptionElement = OptionElement;

    /**
     * This class renders a select box element
     *
     * @param cfg
     * @constructor
     * @class SelectBoxElement
     * @extends HtmlElement
     */
    var SelectBoxElement = function (cfg) {
        SelectBoxElement.superclass.constructor.apply(this, arguments);
    };
    SelectBoxElement.ATTRS = {
        /**
         * Contains an array of primitives or objects of type {key: 'key', value: 'value'}
         *
         * @attribute options
         * @type {Array}
         * @default []
         */
        options: {
            value: []
        },

        /**
         * Default element to be selected
         */

        defaultSelectValue: {
            value: ''
        },
        /**
         * Overrides element attribute from HtmlElement, to set the element to 'select'
         *
         * @readOnly
         * @attribute element
         * @type String
         * @default 'select'
         */
        element: {
            value: 'select',
            readOnly: true
        },

        /**
         * Set this to true if this is a multiple select box
         *
         * @attribute multiple
         * @type String
         * @default ''
         */
        multiple: {
            value: ''
        },

        /**
         * Sets the size of the select box
         *
         * @attribute size
         * @type String
         * @default ''
         */
        size: {
            value: ''
        },

        /**
         * if this is set, the object will listen to the load event and fire a callback method
         *
         * @attribute loadEvent
         * @type String
         * @default ''
         */
        loadEvent: {
            value: '' // 'eventName'
        }
    };
    Y.extend(SelectBoxElement, HtmlElement, {
        initializer: function () {
            var instance = this,
                options = instance.get('options'),
                loadEvent = instance.get('loadEvent'),
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                value;

            var defaultValue = (instance.get('defaultSelectValue')) ? instance.get('defaultSelectValue') : "";
            if (defaultValue) {
                modelInstance.set(name, defaultValue);
            }
            if (modelInstance) {
                value = modelInstance.get(name);
            }
            else {
                value = instance.get('value');
            }

            if (options && options.length > 0) {
                instance.setChildren(instance, options, value, false, defaultValue);
            }
            else {
                if (loadEvent) {
                    Y.on(loadEvent, function (e) {
                        instance.set('options', e.options); // backward compatibility with sync behaviour (selectbox)
                        instance.setChildren(instance, e.options, value, true, defaultValue);
                    });
                }
            }
        },
        setChildren: function (instance, optionList, value, render, defaultValue) {
            var children = [];
            var host = instance.get('host');
            this.defaultValue = "";

            for (var i = 0; i < optionList.length; i++) {
                var option = optionList[i];
                if (option instanceof Object) {
                    this.defaultValue = Y.Lang.isArray(value) ? value.contains(option.key) : value == option.key
                }
                else {
                    this.defaultValue = (defaultValue == option) ? 'selected' : '';
                }


                var optionElement = new Y.OptionElement({
                    element: 'option',
                    htmlContent: Y.Lang.isObject(option) ? option.value : option,
                    value: Y.Lang.isObject(option) ? option.key : option,
                    selected: this.defaultValue
                });

                children.push(optionElement);

                if (render) {
                    optionElement.render(host);
                }
            }

            instance.set('children', children);
        },
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                type = instance.get('type'),
                value = '';
            if (elem.getAttribute('multiple')) {
                value = [];
            }
            elem.get("options").each(function (item) {
                var selected = item.get('selected');
                if (selected) {
                    if (Y.Lang.isArray(value)) {
                        value.push(item.get('value'))
                    }
                    else {
                        value = item.get('value');
                    }
                }
            });

            modelInstance.set(name, value);
        },
        setModelEvents: function (element) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name');
            element.on('change', function (e) {
                instance.changeModelAttribute(e);
            });
            if (modelInstance.get(name)) {
                element.set('value', modelInstance.get(name));
            }
        }
    });
    Y.SelectBoxElement = SelectBoxElement;

    /**
     * This class renders an input element that can be translated using defined languages.
     * Usage:
     *
     *          new Y.TranslatableElement({
     *              label: instance.t('searchBox.title'),
     *              name: FIELD_TITLE,
     *              modelInstance: instance
     *          });
     *
     * The attributes {{#crossLink 'TranslatableElement/modelInstance:attribute'}}{{/crossLink}} and
     * {{#crossLink 'TranslatableElement/name:attribute'}}{{/crossLink}} are required for this type of element
     *
     * @param cfg
     * @constructor
     * @class TranslatableElement
     * @extends HtmlElement
     */
    var TranslatableElement = function (cfg) {
        TranslatableElement.superclass.constructor.apply(this, arguments);
    };
    TranslatableElement.ATTRS = {
        /**
         * Defines the current user languages {{#crossLink 'AbstractWizard/getAvailableLanguages:method'}}{{/crossLink}}
         *
         * @attribute currentLanguage
         * @type String
         * @default ''
         */
        currentLanguage: {
            value: ''
        }
    };
    Y.extend(TranslatableElement, HtmlElement, {
        initializer: function () {
            var instance = this,
                modelInstance = instance.get("modelInstance"),
                name = instance.get('name'),
                defLanguage = modelInstance.getDefaultLanguage(),
                currentLanguage = instance.get('currentLanguage');

            if (!currentLanguage) {
                currentLanguage = defLanguage;
                instance.set('currentLanguage', currentLanguage);
            }

            var input = new Y.InputElement({
                label: instance.get('label'),
                placeholder: modelInstance.get(name)[defLanguage] ? modelInstance.get(name)[defLanguage] : '',
                value: modelInstance.get(name)[currentLanguage] ? modelInstance.get(name)[currentLanguage] : '',
                onChange: function (e) {
                    instance.changeModelAttribute(e);
                }
            });
            instance.set('label', null);
            var buttons = [];
            var languages = modelInstance.getAvailableLanguages();
            for (var i = 0; i < languages.length; i++) {
                var lang = languages[i],
                    btnCssClass = 'btn btn-primary btn-xs btn-lang-' + lang;

                if (lang == defLanguage) {
                    btnCssClass += " btn-active";
                }
                if (modelInstance.get(name)[lang]) {
                    btnCssClass += " btn-translated";
                }

                buttons.push(new Y.HtmlElement({
                    element: 'button',
                    type: 'button',
                    htmlContent: lang,
                    cssClass: btnCssClass,
                    onClick: function (e) {
                        var lang = Y.one(e.currentTarget).getHTML(),
                            dVal = modelInstance.get(name)[defLanguage] ? modelInstance.get(name)[defLanguage] : '',
                            cVal = modelInstance.get(name)[lang] ? modelInstance.get(name)[lang] : '';

                        Y.one(e.currentTarget).ancestor().all('.btn').removeClass('btn-active');
                        Y.one(e.currentTarget).addClass('btn-active');
                        input.get('host').setAttribute('placeholder', dVal);
                        input.get('host').set('value', cVal);
                        instance.set('currentLanguage', lang);
                    }
                }));
            }

            if (!instance.get('cssClass')) {
                instance.set('cssClass', '');
            }

            instance.set('cssClass', instance.get('cssClass') + ' form-group input-translatable');

            instance.set('children', [
                input,
                new Y.HtmlElement({
                    children: buttons,
                    cssClass: 'btn-group'
                })
            ]);
        },
        changeModelAttribute: function (e) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                name = instance.get('name'),
                elem = Y.one(e.currentTarget),
                value = modelInstance.get(name),
                elemValue = elem.get('value'),
                currentLanguage = instance.get('currentLanguage'),
                btn = elem.ancestor('.input-translatable').one('.btn-lang-' + currentLanguage);
            if (!value) {
                value = {};
            }
            if (elemValue) {
                value[currentLanguage] = elemValue;
                if (btn && !btn.hasClass('btn-translated')) {
                    btn.addClass('btn-translated');
                }
            }
            else {
                delete value[currentLanguage];
                if (btn) {
                    btn.removeClass('btn-translated');
                }
            }
            modelInstance.set(name, value);
        }
    });
    Y.TranslatableElement = TranslatableElement;

    /**
     * Renders a publication select element.
     *
     * @param cfg
     * @constructor
     * @class SelectedPublicationsElement
     * @extends HtmlElement
     */
    var SelectedPublicationsElement = function (cfg) {
        SelectedPublicationsElement.superclass.constructor.apply(this, arguments);
    };
    SelectedPublicationsElement.ATTRS = {

        publications: {
            value: []
        },

        sortBy: {
            value: ''
        },

        customOrder: {
            value: []
        },

        labels: {
            value: {}
        },

        singlePublication: {
            value: false
        },

        getSavedPublicationsURL: {
            value: ''
        },

        getMissingPublicationsURL: {
            value: ''
        },

        myPublicationsPageURL: {
            value: ''
        },

        fieldSortBy: {
            value: ''
        },

        sortByCriteria: {
            value: []
        },

        fieldCellarIds: {
            value: ''
        },

        /* backward compatibility */
        fieldCustomOrder: {
            value: ''
        },

        /* backward compatibility */
        fieldPermanentLinks: {
            value: ''
        }

    };
    SelectedPublicationsElement.PUBLICATIONS_LOADED_EVENT = 'publicationsLoadedEvent';

    Y.extend(SelectedPublicationsElement, HtmlElement, {
        initializer: function () {
            var instance = this,
                modelInstance = instance.get("modelInstance"),
                name = instance.get('name'),
                labels = instance.get('labels'),
                fieldSortBy = instance.get('fieldSortBy'),
                sortByCriteria = instance.get('sortByCriteria'),
                fieldCellarIds = instance.get('fieldCellarIds'),
                singlePublication = instance.get('singlePublication');

            if (!instance.get('cssClass')) {
                instance.set('cssClass', '');
            }
            instance.set('cssClass', instance.get('cssClass') + ' selected-publications');

            var children = [];
            if (!singlePublication) {
                children.push(new Y.HtmlElement({
                    cssClass: 'row',
                    htmlContent: labels.availablePublications ?
                        labels.availablePublications.replace('{0}', instance.get('myPublicationsPageURL')) : ''
                }));
            }
            else {
                children.push(new Y.HtmlElement({
                    cssClass: 'row',
                    children: [
                        new Y.RadioElement({
                            label: labels.optionNoPreSelected,
                            value: 'noPreselected',
                            name: 'displayedPublicationOption',
                            modelInstance: modelInstance,
                            checked: !modelInstance.get(fieldCellarIds),
                            onChange: function () {
                                instance.setModelInstanceValue(fieldCellarIds, '');
                                var selectedPublicationsHolder = instance.get('host').one('.selected-publications-holder');
                                if (selectedPublicationsHolder) {
                                    selectedPublicationsHolder.setHTML('');
                                }
                            }
                        }),
                        new Y.RadioElement({
                            label: labels.optionPreSelected ?
                                labels.optionPreSelected.replace('{0}', instance.get('myPublicationsPageURL')) : '',
                            value: 'preselected',
                            name: 'displayedPublicationOption',
                            modelInstance: modelInstance,
                            checked: !!modelInstance.get(fieldCellarIds)
                        })
                    ]
                }));
            }
            children.push(new Y.HtmlElement({
                cssClass: 'row table-holder',
                htmlContent: '<div id="blocking-loader" class="portal-loader" aria-busy="true">' +
                '<span class="loading-image"></span>' +
                '</div>'
            }));
            children.push(new Y.HtmlElement({
                cssClass: 'row button-holder',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'col-xs-4',
                        children: []
                    }),
                    new Y.HtmlElement({
                        cssClass: 'col-xs-4 add-publications-button',
                        children: [
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary',
                                htmlContent: '<i class="glyphicon glyphicon-chevron-down"></i> ' + labels.addPublication,
                                onClick: function (e) {
                                    instance.addSelectedPublications();
                                }
                            })
                        ]
                    }),
                    new Y.HtmlElement({
                        cssClass: 'col-xs-4 add-permanentLink-button',
                        children: [
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-default',
                                htmlContent: labels.addPermanentLink,
                                onClick: function (e) {
                                    instance.addPermanentLink();
                                }
                            })
                        ]
                    })
                ]
            }));
            var selectedPublicationsTitleRow = [];
            selectedPublicationsTitleRow.push(new Y.HtmlElement({
                cssClass: 'col-xs-6 selected-publications-title',
                htmlContent: labels.selectedPublications
            }));
            if (!singlePublication) {
                selectedPublicationsTitleRow.push(new Y.HtmlElement({
                    cssClass: 'col-xs-6 selected-publications-order',
                    children: [
                        new Y.SelectBoxElement({
                            label: labels.sortBy,
                            modelInstance: modelInstance,
                            name: fieldSortBy,
                            options: sortByCriteria,
                            onChange: function (e) {
                                instance.setPublicationsOrder();
                                instance.renderSelectedPublications();
                            }
                        })
                    ]
                }))
            }
            children.push(new Y.HtmlElement({
                cssClass: 'row selected-publications-row',
                children: selectedPublicationsTitleRow
            }));
            children.push(new Y.HtmlElement({
                cssClass: 'row selected-publications-holder',
                children: []
            }));

            instance.set('children', children);
        },

        setSelectedPublications: function (selectedPublications) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                fieldSortBy = instance.get('fieldSortBy'),
                fieldCellarIds = instance.get('fieldCellarIds'),
                fieldCustomOrder = instance.get('fieldCustomOrder'),
                fieldPermanentLinks = instance.get('fieldPermanentLinks'),
                fieldSavedPublications = instance.get('name'),
                singlePublication = instance.get('singlePublication');

            if (singlePublication) {
                // if (selectedPublications && selectedPublications.length > 1) {
                //     // keep only last value from array
                //     selectedPublications = selectedPublications.splice(selectedPublications.length - 1, selectedPublications.length);
                // }
                var displayedPublicationOption = instance.get('host').one('input[name="displayedPublicationOption"][value="preselected"]');
                if (displayedPublicationOption) {
                    displayedPublicationOption.set('checked', 'true');
                }
            }

            instance.set('selectedPublications', selectedPublications);
            instance.setModelInstanceValue(fieldSortBy, instance.get('sortBy') != undefined ? instance.get('sortBy') : '');

            if (!selectedPublications) {
                instance.setModelInstanceValue(fieldCellarIds, singlePublication ? '' : []);
            }
            else {
                var cellarIdsArray = [];
                for (var i = 0; i < selectedPublications.length; i++) {
                    cellarIdsArray.push(selectedPublications[i].cellarId);
                }
                instance.setModelInstanceValue(fieldCellarIds, singlePublication ? cellarIdsArray[0] : cellarIdsArray);
                if (singlePublication && selectedPublications && selectedPublications.length > 0 && 'elif' === selectedPublications[0]['publicationType']) {
                    instance.setModelInstanceValue('publicationType', 'elif');
                }
                else {
                    instance.setModelInstanceValue('publicationType', '');
                }
            }

            /* set empty values to deprecated fields, publication list is saved only in cellarIds field */
            instance.setModelInstanceValue(fieldCustomOrder, '');
            instance.setModelInstanceValue(fieldPermanentLinks, []);

            if (fieldSavedPublications !== fieldCellarIds) {
                instance.setModelInstanceValue(fieldSavedPublications, singlePublication ? '' : []);
            }
        },

        getSelectedPublications: function () {
            return this.get('selectedPublications') || [];
        },

        addAfterRenderEvents: function () {
            this.getSavedPublications();
            Y.on(SelectedPublicationsElement.PUBLICATIONS_LOADED_EVENT, function (e) {
                var instance = e.currentTarget;
                instance.renderPublicationsTable(e.options);
                instance.renderExistingValues(e.options);
            });

        },


        setPublicationsOrder: function (customOrderArray) {
            var instance = this,
                modelInstance = instance.get("modelInstance"),
                fieldSortBy = instance.get('fieldSortBy'),
                selectedPublications = instance.getSelectedPublications();

            var sortBySelectBox = instance.get('host') ? instance.get('host').one('select[name="' + fieldSortBy + '"]') : undefined;
            var orderCriteria = sortBySelectBox ? sortBySelectBox.get('value') : '';

            // order publications by customOrderArray
            if (customOrderArray && customOrderArray.length > 1) {

                instance.set('sortBy', '');
                instance.set('customOrder', customOrderArray);

                if (sortBySelectBox) {
                    sortBySelectBox.set('selectedIndex', 0);
                    instance.setModelInstanceValue(fieldSortBy, '');
                }

                var newOrderSelectedPublications = [];
                for (var i = 0; i < customOrderArray.length; i++) {
                    for (var j = 0; j < selectedPublications.length; j++) {
                        if (selectedPublications[j].cellarId == customOrderArray[i]) {
                            newOrderSelectedPublications.push(selectedPublications[j]);
                            break;
                        }
                    }
                }

                instance.setSelectedPublications(newOrderSelectedPublications);
            }

            // order publications by sort criteria
            else if (orderCriteria) {

                instance.set('sortBy', orderCriteria);
                instance.set('customOrder', []);

                selectedPublications.sort(function (publication1, publication2) {
                    switch (orderCriteria) {
                        case 'AUTHOR':
                            if (publication1.author < publication2.author) {
                                return -1;
                            }
                            if (publication1.author > publication2.author) {
                                return 1;
                            }
                            return 0;
                        case 'PUBLICATION_DATE':
                            if (publication1.date < publication2.date) {
                                return 1;
                            }
                            if (publication1.date > publication2.date) {
                                return -1;
                            }
                            return 0;
                        case 'COLLECTION':
                            if (publication1.collection < publication2.collection) {
                                return -1;
                            }
                            if (publication1.collection > publication2.collection) {
                                return 1;
                            }
                            return 0;
                        case 'SUBJECT':
                            if (publication1.subject < publication2.subject) {
                                return -1;
                            }
                            if (publication1.subject > publication2.subject) {
                                return 1;
                            }
                            return 0;
                        case 'TITLE':
                            if (publication1.title < publication2.title) {
                                return -1;
                            }
                            if (publication1.title > publication2.title) {
                                return 1;
                            }
                            return 0;
                        default:
                            return 0;
                    }
                });

                instance.setSelectedPublications(selectedPublications);
            }
        },

        renderPublicationsTable: function (publications) {
            var instance = this,
                host = instance.get('host'),
                modelInstance = instance.get("modelInstance"),
                tableHolder = host.one('.table-holder'),
                labels = instance.get('labels'),
                singlePublication = instance.get('singlePublication');

            var tableColumns = [
                {key: "no", label: labels.publicationsTableHeader_no, sortable: true},
                {key: "title", label: labels.publicationsTableHeader_documentTitle, sortable: true, allowHTML: true},
                {key: "format", label: labels.publicationsTableHeader_format, sortable: true},
                {key: "language", label: labels.publicationsTableHeader_language, sortable: true},
                {key: "publicationType", label: labels.publicationsTableHeader_publicationType, sortable: false}
            ];
            var tableData = [];
            var publicationsList = [];
            var listOfPubList = []
            var counter = 0;
            var listID = 0;
            var listPubNo = 0; // Number of publications for a list
            var listIcon = '<span class="glyphicon glyphicon-list"></span>'
            if (publications && publications.length > 0) {

                for (var i = 0; i < publications.length; i++) {
                    if (publications[i].type !== 'PUBLICATION') {
                        continue;
                    }
                    else {
                        counter++;
                        publicationsList.push({
                            no: counter,
                            title: publications[i].title +
                            (publications[i].unavailable ?
                                ' (' + modelInstance.t('baseWidgetList.publicationUnavailable') + ')' : ''),
                            format: publications[i].type == 'PUBLICATION' ?
                                publications[i].format : modelInstance.t('baseWidgetList.publicationsList'),
                            language: publications[i].language,
                            cellarId: publications[i].cellarId,
                            date: publications[i].date,
                            author: publications[i].author,
                            collection: publications[i].collection,
                            subject: publications[i].subject,
                            type: publications[i].type,
                            listId: publications[i].listId,
                            listIds: publications[i].listIds,
                            publicationType: publications[i].publicationType,
                        });
                    }

                }

                if (!singlePublication) {
                    for (var i = 0; i < publications.length; i++) {
                        if (publications[i].type == 'LIST') {
                            counter++;
                            listID = (publications[i].listId != undefined) ? publications[i].listId : 0;
                            listPubNo = 0;
                            for (var j = 0; j < publicationsList.length; j++) {
                                if (publicationsList[j].listIds.indexOf(listID) >= 0) {
                                    listPubNo++;
                                }
                            }

                            listOfPubList.push({
                                no: counter,
                                title: (publications[i].title != undefined) ?
                                    listIcon.concat(" ",
                                        publications[i].title,
                                        " ",
                                        "(",
                                        listPubNo,
                                        " ",
                                        modelInstance.t('baseWidgetList.publications'),
                                        ")")
                                    : listIcon.concat(" ", listPubNo),
                                format: " ",
                                language: publications[i].language,
                                cellarId: publications[i].cellarId,
                                date: publications[i].date,
                                author: publications[i].author,
                                collection: publications[i].collection,
                                subject: publications[i].subject,
                                type: publications[i].type,
                                listId: publications[i].listId
                            });
                        }
                    }
                }
            }

            tableData = publicationsList.concat(listOfPubList);
            tableData.reverse(); //display the list reversed PORTALMSP-1923

            tableHolder.setHTML('');
            var dataTable = new Y.DataTable({
                columns: tableColumns,
                data: tableData
            }).render(tableHolder);

            instance.set('dataTable', dataTable);
            instance.set('publicationsList', publicationsList);

            tableHolder.all('tbody tr').each(function (element) {
                element.on('click', function () {
                    if (singlePublication) {
                        this.get('parentNode').all('tr').removeClass('selected');
                    }
                    this.toggleClass('selected');
                });
            });

            dataTable.before('sort', function () {
                var dataTableInstance = this;
                var cellarIds = [];
                tableHolder.all('tBody tr.selected').each(function (publicationRow) {
                    var record = dataTableInstance.getRecord(publicationRow.guid());
                    if (record) {
                        var json = record.toJSON();
                        if (json && json.cellarId) {
                            cellarIds.push(json.cellarId);
                        }
                    }
                });
                instance.set('tempSelectedCellarIds', cellarIds);
            });
            dataTable.after('sort', function () {
                var dataTableInstance = this;
                var cellarIds = instance.get('tempSelectedCellarIds');

                tableHolder.all('tBody tr').each(function (publicationRow) {
                    publicationRow.on('click', function () {
                        if (singlePublication) {
                            this.get('parentNode').all('tr').removeClass('selected');
                        }
                        this.toggleClass('selected');
                    });
                    if (cellarIds) {
                        var record = dataTableInstance.getRecord(publicationRow.guid());
                        if (record) {
                            var json = record.toJSON();
                            if (json && json.cellarId && cellarIds.indexOf(json.cellarId) != -1) {
                                publicationRow.addClass('selected');
                            }
                        }
                    }
                });
            });
        },

        addSelectedPublications: function () {

            var instance = this,
                host = instance.get('host'),
                tableHolder = host.one('.table-holder'),
                dataTable = instance.get('dataTable'),
                selectedPublications = instance.getSelectedPublications(),
                singlePublication = instance.get('singlePublication'),
                pubList = instance.get('publicationsList');
            if (!selectedPublications) {
                selectedPublications = [];
            }
            var addIfNotPresent = function (json) {
                var bIsPresent = false;
                selectedPublications.forEach(function (element) {
                    if (element.cellarId == json.cellarId) {
                        bIsPresent = true;
                    }
                });

                if (!bIsPresent) {
                    selectedPublications.push(json);
                }
            }

            tableHolder.all('tBody tr.selected').each(function (publicationRow) {
                var record = dataTable.getRecord(publicationRow.guid());
                if (record) {
                    var json = record.toJSON();
                    if (json && json.cellarId) {
                        for (var i = 0; i < selectedPublications.length; i++) {
                            if (selectedPublications[i] && selectedPublications[i].cellarId == json.cellarId) {
                                return;
                            }
                        }
                        addIfNotPresent(json);
                    }
                    else if (json && json.type == 'LIST') {
                        var listId = json.listId;
                        //selectedPublications = [];
                        //Add all publications of the list
                        for (var i = 0; i < pubList.length; i++) {
                            if (pubList[i].listIds.indexOf(listId) >= 0) {
                                addIfNotPresent(pubList[i]);
                            }
                        }

                        // dataTable.get('data').each(function(record) {
                        //     var jsonObject = record.toJSON();
                        //     if (jsonObject.listId == listId && jsonObject.type == 'PUBLICATION') {
                        //         selectedPublications.push(jsonObject);
                        //     }
                        // });
                    }
                }
            });
            instance.setSelectedPublications(selectedPublications);
            instance.setPublicationsOrder();
            instance.renderSelectedPublications();
        },

        addPermanentLink: function () {
            var instance = this,
                selectedPublications = instance.getSelectedPublications(),
                labels = instance.get('labels');

            var panel = new Y.Panel({
                bodyContent: labels.addPermanentLink + '<br/>' + '<input type="text"/>',
                width: 400,
                centered: true,
                modal: true,
                zIndex: 1000,
                render: instance.get('host'),
                buttons: [
                    {
                        value: labels.addPublication,
                        section: Y.WidgetStdMod.FOOTER,
                        action: function (e) {
                            e.preventDefault();
                            var inputField = e.target.get('parentNode').get('parentNode').get('parentNode').one('input');
                            var permanentLink = inputField ? inputField.get('value') : '';
                            var publicationType='';
                            if(permanentLink.search("bibliographic-details")>0){
                                publicationType='elif';
                            }

                            var cellarId = permanentLink ? instance._getCellarId(permanentLink) : '';

                            if (cellarId) {
                                var publicationExists = false;
                                for (var i = 0; i < selectedPublications.length; i++) {
                                    if (selectedPublications[i].cellarId == cellarId) {
                                        publicationExists = true;
                                        break;
                                    }
                                }
                                if (!publicationExists) {
                                    selectedPublications.push({
                                        cellarId: cellarId,
                                        author: '',
                                        collection: '',
                                        date: '',
                                        format: instance._getFormat(permanentLink),
                                        language: instance._getLanguage(permanentLink),
                                        subject: '',
                                        title: cellarId,
                                        publicationType:publicationType
                                    });
                                    instance.setSelectedPublications(selectedPublications);
                                    instance.fillSelectedPublicationData(function () {
                                        instance.setPublicationsOrder();
                                        instance.renderSelectedPublications();
                                        panel.hide();
                                        inputField.get('parentNode').removeClass('alert');
                                    });
                                }
                                else {
                                    panel.hide();
                                }
                            }
                            else {
                                inputField.get('parentNode').addClass('alert');
                            }
                        }
                    }
                ]
            });
            panel.show();


        },

        renderExistingValues: function (userSavedPublications) {

            var instance = this,
                modelInstance = instance.get('modelInstance'),
                fieldCellarIds = instance.get('fieldCellarIds'),
                fieldCustomOrder = instance.get('fieldCustomOrder'),
                fieldPermanentLinks = instance.get('fieldPermanentLinks'),
                fieldSavedPublications = instance.get('name'),
                singlePublication = instance.get('singlePublication');


            var cellarIdsSavedValue = modelInstance.get(fieldCellarIds);
            var savedPublicationsSavedValue = modelInstance.get(fieldSavedPublications);
            var customOrderSavedValue = modelInstance.get(fieldCustomOrder);
            var permanentLinksSavedValue = modelInstance.get(fieldPermanentLinks);

            if (!userSavedPublications) {
                userSavedPublications = [];
            }
            if (!cellarIdsSavedValue) {
                cellarIdsSavedValue = [];
            }
            if (!permanentLinksSavedValue) {
                permanentLinksSavedValue = [];
            }

            var selectedPublications = [];
            for (var i = 0; i < cellarIdsSavedValue.length; i++) {

                var currentCellarId = singlePublication ? instance._getCellarId(cellarIdsSavedValue) : cellarIdsSavedValue[i];
                if (!currentCellarId) {
                    continue;
                }

                var publication = {
                    cellarId: currentCellarId,
                    author: '',
                    collection: '',
                    date: '',
                    format: '',
                    language: '',
                    subject: '',
                    title: currentCellarId,
                    unavailable: false,
                    publicationType:modelInstance.get('publicationType')
                };
                for (var j = 0; j < userSavedPublications.length; j++) {
                    if (userSavedPublications[j].cellarId == currentCellarId) {
                        if (userSavedPublications[j].title) {
                            publication.title = userSavedPublications[j].title;
                        }
                        if (userSavedPublications[j].format) {
                            publication.format = userSavedPublications[j].format;
                        }
                        if (userSavedPublications[j].language) {
                            publication.language = userSavedPublications[j].language;
                        }
                        if (userSavedPublications[j].author) {
                            publication.author = userSavedPublications[j].author;
                        }
                        if (userSavedPublications[j].collection) {
                            publication.collection = userSavedPublications[j].collection;
                        }
                        if (userSavedPublications[j].date) {
                            publication.date = userSavedPublications[j].date;
                        }
                        if (userSavedPublications[j].subject) {
                            publication.subject = userSavedPublications[j].subject;
                        }
                        if (userSavedPublications[j].unavailable) {
                            publication.unavailable = userSavedPublications[j].unavailable ? true : false;
                        }
                        if (userSavedPublications[j].publicationType) {
                            publication.publicationType = userSavedPublications[j].publicationType;
                        }
                        break;
                    }
                }
                selectedPublications.push(publication);
                if (singlePublication) {
                    break;
                }
            }

            if ('undefined' === typeof savedPublicationsSavedValue) {
                savedPublicationsSavedValue = [];
            }
            for (var i = 0; i < savedPublicationsSavedValue.length; i++) {
                var currentCellarId = singlePublication ? instance._getCellarId(savedPublicationsSavedValue) : savedPublicationsSavedValue[i];
                // check if publication exists already

                var publicationExists = false;
                for (var j = 0; j < selectedPublications.length; j++) {
                    if (selectedPublications[j].cellarId == currentCellarId) {
                        publicationExists = true;
                        break;
                    }
                }
                if (publicationExists) {
                    continue;
                }

                var publication = {
                    cellarId: currentCellarId,
                    author: '',
                    collection: '',
                    date: '',
                    format: '',
                    language: '',
                    subject: '',
                    title: currentCellarId,
                    unavailable: false,
                    publicationType:modelInstance.get('publicationType')
                };
                for (var j = 0; j < userSavedPublications.length; j++) {
                    if (userSavedPublications[j].cellarId == currentCellarId) {
                        if (userSavedPublications[j].title) {
                            publication.title = userSavedPublications[j].title;
                        }
                        if (userSavedPublications[j].format) {
                            publication.format = userSavedPublications[j].format;
                        }
                        if (userSavedPublications[j].language) {
                            publication.language = userSavedPublications[j].language;
                        }
                        if (userSavedPublications[j].author) {
                            publication.author = userSavedPublications[j].author;
                        }
                        if (userSavedPublications[j].collection) {
                            publication.collection = userSavedPublications[j].collection;
                        }
                        if (userSavedPublications[j].date) {
                            publication.date = userSavedPublications[j].date;
                        }
                        if (userSavedPublications[j].subject) {
                            publication.subject = userSavedPublications[j].subject;
                        }
                        if (userSavedPublications[j].unavailable) {
                            publication.unavailable = userSavedPublications[j].unavailable ? true : false;
                        }
                        break;
                    }
                }
                selectedPublications.push(publication);
                if (singlePublication) {
                    break;
                }
            }

            if ('undefined' === typeof permanentLinksSavedValue) {
                permanentLinksSavedValue = [];
            }
            for (var i = 0; i < permanentLinksSavedValue.length; i++) {
                var permanentLink = permanentLinksSavedValue[i];
                var cellarId = instance._getCellarId(permanentLink);

                // check if publication exists already
                var publicationExists = false;
                for (var j = 0; j < selectedPublications.length; j++) {
                    if (selectedPublications[j].cellarId == cellarId) {
                        publicationExists = true;
                        break;
                    }
                }
                if (publicationExists) {
                    continue;
                }

                var publication = {
                    cellarId: cellarId,
                    author: '',
                    collection: '',
                    date: '',
                    format: instance._getFormat(permanentLink),
                    language: instance._getLanguage(permanentLink),
                    subject: '',
                    title: cellarId,
                    unavailable: false
                };
                for (var j = 0; j < userSavedPublications.length; j++) {
                    if (userSavedPublications[j].cellarId == cellarId) {
                        if (userSavedPublications[j].title) {
                            publication.title = userSavedPublications[j].title;
                        }
                        if (userSavedPublications[j].format) {
                            publication.format = userSavedPublications[j].format;
                        }
                        if (userSavedPublications[j].language) {
                            publication.language = userSavedPublications[j].language;
                        }
                        if (userSavedPublications[j].author) {
                            publication.author = userSavedPublications[j].author;
                        }
                        if (userSavedPublications[j].collection) {
                            publication.collection = userSavedPublications[j].collection;
                        }
                        if (userSavedPublications[j].date) {
                            publication.date = userSavedPublications[j].date;
                        }
                        if (userSavedPublications[j].subject) {
                            publication.subject = userSavedPublications[j].subject;
                        }
                        if (userSavedPublications[j].unavailable) {
                            publication.unavailable = userSavedPublications[j].unavailable ? true : false;
                        }
                        break;
                    }
                }
                selectedPublications.push(publication);
            }


            if (customOrderSavedValue) {

                var customOrderJSON = [];
                try {
                    customOrderJSON = JSON.parse(customOrderSavedValue);
                } catch (e) {
                    customOrderJSON = customOrderSavedValue;
                }

                var customOrderArray = [];

                for (var i = 0; i < customOrderJSON.length; i++) {
                    customOrderArray.push(customOrderJSON[i].key);
                }
                var isDifferentOrder = false;
                for (var i = 0; i < customOrderArray.length; i++) {
                    if (customOrderArray[i] != (selectedPublications[i] ? selectedPublications[i].cellarId : undefined)) {
                        isDifferentOrder = true;
                        break;
                    }
                }
                instance.setPublicationsOrder(isDifferentOrder ? customOrderArray : undefined);
            }
            else {
                instance.setPublicationsOrder();
            }
            instance.setSelectedPublications(selectedPublications);
            instance.fillSelectedPublicationData(function () {
                instance.renderSelectedPublications();
            });

        },

        fillSelectedPublicationData: function (successCallback) {
            var instance = this,
                selectedPublications = instance.getSelectedPublications();

            var missingInfoPublications = [];
            for (var i = 0; i < selectedPublications.length; i++) {
                if (!selectedPublications[i].title || selectedPublications[i].title == selectedPublications[i].cellarId) {
                    missingInfoPublications.push(selectedPublications[i].cellarId);
                }
            }

            if (missingInfoPublications && missingInfoPublications.length > 0) {
                var getMissingPublicationsURL = instance.get('getMissingPublicationsURL');
                getMissingPublicationsURL += missingInfoPublications.join(',');

                Y.io(getMissingPublicationsURL, {
                    method: 'GET',
                    sync: false,
                    on: {
                        complete: function (id, response) {
                            var responseJson = JSON.parse(response.responseText);
                            for (var i = 0; i < responseJson.length; i++) {
                                for (var j = 0; j < selectedPublications.length; j++) {
                                    if (selectedPublications[j].cellarId == responseJson[i].cellarId) {
                                        selectedPublications[j].title = responseJson[i].title;
                                        selectedPublications[j].author = responseJson[i].author;
                                        selectedPublications[j].date = responseJson[i].date;
                                        selectedPublications[j].language = responseJson[i].language;
                                        selectedPublications[j].subject = responseJson[i].subject;
                                        selectedPublications[j].format = responseJson[i].format;
                                        selectedPublications[j].unavailable = responseJson[i].unavailable ? true : false
                                        break;
                                    }
                                }
                            }
                            instance.setSelectedPublications(selectedPublications);
                            if (successCallback && typeof successCallback == 'function') {
                                successCallback();
                            }
                        }
                    }
                });
            }
            else {
                if (successCallback && typeof successCallback == 'function') {
                    successCallback();
                }
            }
        },

        _getCellarId: function (content) {
            var CELLAR_REGEX = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/g;
            try {
                CELLAR_REGEX.lastIndex = 0;
                var match = CELLAR_REGEX.exec(content);
                return match[0];
            } catch (exception) {
                return undefined;
            }
        },

        _getLanguage: function (permanentLink) {
            if (!permanentLink) {
                return '';
            }
            return this._getPermanentLinkValue(permanentLink, 'language');
        },

        _getFormat: function (permanentLink) {
            if (!permanentLink) {
                return '';
            }
            return this._getPermanentLinkValue(permanentLink, 'format');
        },

        _getPermanentLinkValue: function (permanentLink, valueType) {
            if (!permanentLink || permanentLink.indexOf('/') == -1 || !valueType) {
                return '';
            }
            var permanentLinkGroups = permanentLink.split('/');
            for (var i = 0; i < permanentLinkGroups.length; i++) {
                if (permanentLinkGroups[i].indexOf(valueType) != -1) {
                    return permanentLinkGroups[i].split('-') && permanentLinkGroups[i].split('-').length == 2 ?
                        permanentLinkGroups[i].split('-')[1] : '';
                }
            }
        },

        renderSelectedPublications: function () {
            var instance = this,
                host = instance.get('host'),
                selectedPublications = instance.getSelectedPublications(),
                selectedPublicationsHolder = host.one('.selected-publications-holder'),
                singlePublication = instance.get('singlePublication'),
                modelInstance = instance.get('modelInstance'),
                publicationUnavailableLabel = modelInstance.t('baseWidgetList.publicationUnavailable');

            selectedPublicationsHolder.setHTML('');

            if (!selectedPublications) {
                return;
            }
            for (var i = 0; i < selectedPublications.length; i++) {
                var publication = selectedPublications[i];

                var publicationTitle = publication.title;
                if (!publicationTitle) {
                    publicationTitle = publication.cellarId;
                }
                if (publication.unavailable) {
                    if (!publicationTitle) {
                        publicationTitle = publicationUnavailableLabel;
                    }
                    else {
                        publicationTitle += ' (' + publicationUnavailableLabel + ')';
                    }
                }

                selectedPublicationsHolder.append(
                    '<div class="publication clearfix' + (publication.unavailable ? ' publication-unavailable' : '') +
                    '" data-value="' + publication.cellarId + '">' +
                    (singlePublication ? '' : ' <span class="icon-move"></span>') +
                    ' <span class="pub-title">' + publicationTitle + '</span>' +
                    ' <span class="icon-remove"></span>' +
                    '</div>');
            }

            selectedPublicationsHolder.all('.publication').each(function (node) {
                node.one('.icon-remove').on('click', function () {
                    instance.removePublication(this.get('parentNode'));
                });
                if (singlePublication) {
                    return;
                }
                var drag = new Y.DD.Drag({
                    node: node,
                    target: {
                        padding: '0 0 0 20'
                    }
                });
                drag.plug(Y.Plugin.DDProxy, {
                    moveOnEnd: false
                }).plug(Y.Plugin.DDConstrained, {
                    constrain2node: selectedPublicationsHolder.get('id')
                });
                var drop = new Y.DD.Drop({
                    node: node
                });
            });

            instance.attachDragDropEvents();
        },

        attachDragDropEvents: function () {
            var instance = this,
                goingUp = false,
                lastY = 0;

            if (instance.get('singlePublication')) {
                return;
            }

            Y.DD.DDM.on('drop:over', function (e) {
                var drag = e.drag.get('node');
                var drop = e.drop.get('node');

                if (drop.hasClass('publication')) {
                    if (!goingUp) {
                        drop = drop.get('nextSibling');
                    }
                    e.drop.get('node').get('parentNode').insertBefore(drag, drop);
                    e.drop.sizeShim();
                }
            });

            Y.DD.DDM.on('drag:drag', function (e) {
                var y = e.target.lastXY[1];
                goingUp = y < lastY;
                lastY = y;
            });

            Y.DD.DDM.on('drag:start', function (e) {
                var drag = e.target;
                drag.get('node').setStyle('opacity', '.25');
                drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
                drag.get('dragNode').setStyles({
                    opacity: '.5',
                    borderColor: drag.get('node').getStyle('borderColor'),
                    backgroundColor: drag.get('node').getStyle('backgroundColor')
                });
            });
            Y.DD.DDM.on('drag:end', function (e) {
                var node = e.target.get('node');
                node.setStyles({
                    visibility: '',
                    opacity: '1'
                });
                var cellarIds = [];
                node.get('parentNode').all('.publication').each(function (publication) {
                    cellarIds.push(publication.getAttribute('data-value'));
                });
                instance.setPublicationsOrder(cellarIds);

            });
            Y.DD.DDM.on('drag:drophit', function (e) {
                var drop = e.drop.get('node');
                var drag = e.drag.get('node');
                if (drop.hasClass('selected-publications-holder')) {
                    if (!drop.contains(drag)) {
                        drop.appendChild(drag);
                    }
                }
            });

        },

        removePublication: function (publicationRow) {
            var instance = this,
                selectedPublications = instance.getSelectedPublications(),
                cellarId = publicationRow.getAttribute('data-value'),
                removedFromArray = false;

            if (selectedPublications && cellarId) {
                for (var i = 0; i < selectedPublications.length; i++) {
                    if (cellarId == selectedPublications[i].cellarId) {
                        selectedPublications.splice(i, 1);
                        removedFromArray = true;
                        break;
                    }
                }
            }
            if (removedFromArray) {
                instance.setSelectedPublications(selectedPublications);
                publicationRow.remove();
            }
        },

        getSavedPublications: function () {
            var instance = this;
            var getSavedPublicationsURL = instance.get('getSavedPublicationsURL');

            if (!getSavedPublicationsURL) {
                return;
            }
            Y.io(getSavedPublicationsURL, {
                method: 'GET',
                sync: false,
                on: {
                    complete: function (id, response) {
                        var json = JSON.parse(response.responseText);
                        var jsonSorted = json.sort(function (a, b) {
                            if (b.title == undefined) {
                                return -1
                            }
                            else if (a.title == undefined) {
                                return 1;
                            }
                            else {
                                return b.title.toLowerCase() < a.title.toLowerCase() ? 1
                                    : b.title.toLowerCase() > a.title.toLowerCase() ? -1
                                        : 0;
                            }
                        });
                        Y.fire(SelectedPublicationsElement.PUBLICATIONS_LOADED_EVENT, {
                            currentTarget: instance,
                            options: jsonSorted
                        });
                    }
                }
            });
        },

        setModelInstanceValue: function (field, value) {
            var instance = this,
                modelInstance = instance.get('modelInstance');
            if (field) {
                modelInstance.set(field, value);
            }
        }
    });
    Y.SelectedPublicationsElement = SelectedPublicationsElement;

    /**
     * Renders a SearchSourceElement
     *
     * @param cfg
     * @constructor
     * @class SearchSourceElement
     * @extends HtmlElement
     */
    var SearchSourceElement = function (cfg) {
        SearchSourceElement.superclass.constructor.apply(this, arguments);
    };
    SearchSourceElement.ATTRS = {

        labels: {
            value: {}
        },

        fieldSource: {
            value: ''
        },

        fieldSavedSearch: {
            value: ''
        },

        fieldExcluded: {
            value: ''
        },

        getSavedSearchesURL: {
            value: ''
        },

        mySearchesPageURL: {
            value: ''
        }

    };
    SearchSourceElement.SEARCHES_LOADED_EVENT = 'searchesLoadedEvent';

    Y.extend(SearchSourceElement, HtmlElement, {
        initializer: function () {
            var instance = this,
                modelInstance = instance.get("modelInstance"),
                name = instance.get('name'),
                labels = instance.get('labels'),
                fieldSource = instance.get('fieldSource'),
                fieldExcluded = instance.get('fieldExcluded');

            if (!instance.get('cssClass')) {
                instance.set('cssClass', '');
            }
            instance.set('cssClass', instance.get('cssClass') + ' search-source');

            var children = [];
            children.push(new Y.HtmlElement({
                cssClass: 'sourceType',
                children: [
                    new Y.RadioElement({
                        label: labels.radioSearchWidget,
                        value: 'searchWidget',
                        modelInstance: modelInstance,
                        name: fieldSource,
                        checked: modelInstance.get(fieldSource) == 'searchWidget',
                        cssClass: 'row border-top-twenty'
                    }),
                    new Y.RadioElement({
                        label: labels.radioAvailableSearches ?
                            labels.radioAvailableSearches.replace('{0}', instance.get('mySearchesPageURL')) : '',
                        value: 'search',
                        modelInstance: modelInstance,
                        name: fieldSource,
                        checked: modelInstance.get(fieldSource) == 'search',
                        cssClass: 'row border-top-twenty'
                    })
                ]
            }));

            children.push(new Y.HtmlElement({
                cssClass: 'row tableRow',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'table-holder',
                        children: [
                            new Y.HtmlElement({
                                cssClass: 'mySearches-table-holder',
                                children: []
                            })
                        ]
                    }),
                    new Y.HtmlElement({
                        cssClass: 'permanentLink-holder',
                        children: [
                            new Y.HtmlElement({
                                label: labels.exclude,
                                htmlContent: labels.excludeDescription
                            }),
                            new Y.TextAreaElement({
                                modelInstance: modelInstance,
                                name: instance.get('fieldExcluded'),
                                value: modelInstance.get('fieldExcluded')
                            })
                        ]
                    })

                ]
            }));
            instance.set('children', children);
        },

        addAfterRenderEvents: function () {
            this.getMySavedSearches();
            Y.on(SearchSourceElement.SEARCHES_LOADED_EVENT, function (e) {
                var instance = e.currentTarget;
                instance.renderSavedSearchesTable(e.options);
            });
        },

        getMySavedSearches: function () {
            var instance = this;
            var getSavedSearchesURL = instance.get('getSavedSearchesURL');

            if (!getSavedSearchesURL) {
                return;
            }
            Y.io(getSavedSearchesURL, {
                method: 'GET',
                sync: false,
                on: {
                    complete: function (id, response) {
                        var json = JSON.parse(response.responseText);
                        Y.fire(SearchSourceElement.SEARCHES_LOADED_EVENT, {
                            currentTarget: instance,
                            options: json
                        });
                    }
                }
            });
        },

        renderSavedSearchesTable: function (savedSearches) {
            var instance = this,
                host = instance.get('host'),
                modelInstance = instance.get("modelInstance"),
                tableHolder = host.one('.mySearches-table-holder'),
                labels = instance.get('labels'),
                fieldSavedSearch = instance.get('fieldSavedSearch'),
                savedSearchValue = modelInstance.get(fieldSavedSearch);

            var tableColumns = [
                {key: "no", label: labels.tableHeader_no, sortable: true},
                {key: "name", label: labels.tableHeader_searchName, sortable: true},
                {key: "type", label: labels.tableHeader_searchType, sortable: true}
            ];
            var tableData = [];
            if (savedSearches && savedSearches.length > 0) {
                for (var i = 0; i < savedSearches.length; i++) {
                    var searchType = labels.searchType_simple;
                    switch (savedSearches[i].type) {
                        case 'SIMPLE': {
                            searchType = labels.searchType_simple;
                            break;
                        }
                        case 'ADVANCED': {
                            searchType = labels.searchType_advanced;
                            break;
                        }
                        case 'BROWSE_BY_SUBJECT': {
                            searchType = labels.searchType_browseBySubject;
                            break;
                        }
                        case 'SPARQL': {
                            searchType = labels.searchType_sparql;
                            break;
                        }
                        case 'ELIF': {
                            searchType = labels.searchType_elif;
                            break;
                        }
                        default: {
                            searchType = labels.searchType_simple;
                            break;
                        }
                    }
                    tableData.push({
                        no: i + 1,
                        name: savedSearches[i].name,
                        type: searchType,
                        id: savedSearches[i].id
                    });
                }
            }

            tableHolder.setHTML('');
            var dataTable = new Y.DataTable({
                columns: tableColumns,
                data: tableData
            }).render(tableHolder);

            instance.set('dataTable', dataTable);

            tableHolder.all('tbody tr').each(function (element) {
                var record = dataTable.getRecord(element.guid());
                if (record) {
                    var json = record.toJSON();
                    if (json && json.id && savedSearchValue && json.id == savedSearchValue) {
                        element.addClass('selected');
                    }
                }
                element.on('click', function () {
                    this.get('parentNode').all('tr').removeClass('selected');
                    this.addClass('selected');
                    var record = dataTable.getRecord(element.guid());
                    if (record) {
                        var json = record.toJSON();
                        if (json && json.id) {
                            instance.setSelectedSearch(json.id)
                        }
                    }
                });
            });

            dataTable.before('sort', function () {
                var dataTableInstance = this;
                tableHolder.all('tBody tr.selected').each(function (publicationRow) {
                    var record = dataTableInstance.getRecord(publicationRow.guid());
                    if (record) {
                        var json = record.toJSON();
                        if (json && json.id) {
                            instance.set('tempSelectedSearch', json.id);
                        }
                    }
                });
            });
            dataTable.after('sort', function () {
                var dataTableInstance = this;
                var tempSelectedSearch = instance.get('tempSelectedSearch');

                tableHolder.all('tBody tr').each(function (publicationRow) {
                    var record = dataTableInstance.getRecord(publicationRow.guid());
                    if (record) {
                        var json = record.toJSON();
                        if (json && json.id && json.id == tempSelectedSearch) {
                            publicationRow.addClass('selected');
                        }
                    }

                    publicationRow.on('click', function () {
                        this.get('parentNode').all('tr').removeClass('selected');
                        this.addClass('selected');
                        var record = dataTableInstance.getRecord(element.guid());
                        if (record) {
                            var json = record.toJSON();
                            if (json && json.id) {
                                instance.setSelectedSearch(json.id)
                            }
                        }
                    });
                });
            });
        },

        setSelectedSearch: function (selectedSearchId) {
            var instance = this,
                modelInstance = instance.get('modelInstance'),
                fieldName = instance.get('fieldSavedSearch');

            modelInstance.set(fieldName, selectedSearchId);
        }
    });
    Y.SearchSourceElement = SearchSourceElement;

    /**
     * Enriches an input element with autocomplete
     *
     * @param cfg
     * @constructor
     * @class AutoCompleteElement
     * @extends InputElement
     */
    var AutoCompleteElement = function (cfg) {
        AutoCompleteElement.superclass.constructor.apply(this, arguments);
    };
    AutoCompleteElement.ATTRS = {
        /**
         * The options to search in. Represents an array of key-value objects
         *
         *      [{key: 'key', value: 'value'}]
         *
         * If the source is set, the search is done on the server
         *
         * @attribute options
         * @type {Array}
         * @default []
         */
        options: {
            value: []
        },


        /**
         * The source is the url that autocomplete module will call for the values.
         * The server will return an array of key-value objects
         *
         *      [{key: 'key', value: 'value'}]
         *
         * @attribute source
         * @type String
         * @default ''
         */
        source: {
            value: ''
        },

        /**
         * The namespace used to cache the objects returned by the async callback.
         *
         * @attribute cacheNamespace
         * @type String
         * @default ''
         */
        cacheNamespace: {
            value: ''
        },

        /**
         * An array of keys with the selected options.
         *
         * @attribute selectedOptions
         * @type Array
         * @default []
         */
        selectedOptions: {
            value: []
        }
    };
    Y.extend(AutoCompleteElement, InputElement, {
        wrapWithLabel: function (elem) {
            var instance = this, i,
                host = instance.get('host'),
                selectedOptions = instance.get('selectedOptions'),
                selectedElements = Y.Node.create('<div class="selected-elements nav nav-pills"></div>');

            var wrapper = Y.Node.create('<div class="form-group"></div>');
            wrapper.append(selectedElements);
            if (instance.get('label')) {
                var label = Y.Node.create('<label></label>');
                label.setHTML(instance.get('label'));
                label.set('for', elem.get('id'));
                wrapper.append(label);
            }
            wrapper.append(elem);

            if (instance.get('wrapperCssClass')) {
                wrapper.addClass(instance.get('wrapperCssClass'));
            }
            if (selectedOptions && selectedOptions.length > 0) {
                for (i = 0; i < selectedOptions.length; i++) {
                    instance._addSelectedElement(selectedOptions[i], false);
                }
            }

            return wrapper;
        },

        /**
         * Method used to process the selected options. Used when an option is selected or when the element has
         * {{#crossLink 'AutoCompleteElement/value:attribute'}}{{/crossLink}} attribute set
         *
         * @method _addSelectedElement
         * @param obj {Object} an object with the properties 'key' and 'value'
         * @param update
         * @private
         */
        _addSelectedElement: function (obj, update) {
            var instance = this,
                host = instance.get('host'), result,
                source = instance.get('source'),
                options = source ? Liferay[instance.get('cacheNamespace')] || [] : instance.get('options'),
                i;

            if (!Y.Lang.isObject(obj)) {
                var key = obj;
                for (i = 0; i < options.length; i++) {
                    if (key == options[i].key) {
                        result = options[i];
                        break;
                    }
                }
            }
            else {
                result = obj;
                if (result && source) {
                    // cache the result
                    var found = false;
                    for (i = 0; i < options.length; i++) {
                        if (result.key == options[i].key) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        options.push(result);
                        Liferay[instance.get('cacheNamespace')] = options;
                    }
                }
            }
            if (!Y.Lang.isObject(result)) {
                return;
            }

            var selectedElements = host.ancestor(".form-group").one(".selected-elements"),
                elem = Y.Node.create('<li><a href="#">' + result.value + ' <span>X</span></a></li>'),
                selectedOptions = instance.get('selectedOptions');
            if (!Y.Lang.isArray(selectedOptions)) {
                selectedOptions = [];
            }

            elem.setData("data-value", result.key);
            selectedElements.append(elem);
            host.set('value', '');
            selectedElements.all('li span').on('click', function (e) {
                var target = Y.one(e.currentTarget).ancestor('li'),
                    value = target.getData("data-value"),
                    selectedOptions = instance.get('selectedOptions');
                target.remove(true);
                selectedOptions.splice(selectedOptions.indexOf(value), 1);
                instance.set('selectedOptions', selectedOptions);
            });
            if (update) {
                selectedOptions.push(result.key);
                instance.set('selectedOptions', selectedOptions);
            }
        },
        addAfterRenderEvents: function () {
            var instance = this,
                host = instance.get('host'),
                source = instance.get('source'),
                options = source ? Liferay[instance.get('cacheNamespace')] || [] : instance.get('options'),
                selectedOptions = instance.get('selectedOptions');

            host.plug(Y.Plugin.AutoComplete, {
                resultFormatter: function (query, results) {
                    return Y.Array.map(results, function (result) {
                        // Use string substitution to fill out the tweet template and
                        // return an HTML string for this result.
                        return Y.Lang.sub(AUTOCOMPLETE_TEMPLATE, {
                            key: result.raw.key,
                            value: result.raw.value
                        });
                    })
                },
//                resultFilters: function(query, results){
//                    return instance._autocompleteFilter(query, results);
//                },
                resultTextLocator: function (result) {
                    return result.key + ":" + result.value
                },
                source: source ? source : options
            });

            host.ac.after('select', function (e) {
                var result = e.result.raw,
                    selectedOptions = instance.get('selectedOptions');
                if (!Y.Lang.isArray(selectedOptions)) {
                    selectedOptions = [];
                }
                for (i = 0; i < selectedOptions.length; i++) {
                    if (selectedOptions[i] == result.key) {
                        return;
                    }
                }
                instance._addSelectedElement(result, true);
            });
        }
    });

    Y.AutoCompleteElement = AutoCompleteElement;

    /**
     * Enriches an input element with date selection popup
     *
     * @param cfg
     * @constructor
     * @class InputDateElement
     * @extends InputElement
     */
    var InputDateElement = function (cfg) {
        InputDateElement.superclass.constructor.apply(this, arguments);
    };
    Y.extend(InputDateElement, InputElement, {
        addAfterRenderEvents: function () {
            var instance = this,
                host = instance.get('host'),
                options = instance.get('options'),
                id = instance.get('name');

            function guid() {
                function s4() {
                    return Math.floor((1 + Math.random()) * 0x10000)
                        .toString(16)
                        .substring(1);
                }

                return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
                    s4() + '-' + s4() + s4() + s4();
            }

            id += guid().replace("-", "");
            instance.set("id", id);
            new Y.DatePicker({
                trigger: '#' + id,
                mask: '%Y/%m/%d',
                popover: {
                    zIndex: 1
                }
            });
        }
    });
    Y.InputDateElement = InputDateElement;


    /**
     * Provides the method of creating tables
     *
     * @param cfg
     * @constructor
     * @class InputDateElement
     * @extends InputElement
     */
    var TableElement = function (cfg) {
        TableElement.superclass.constructor.apply(this, arguments);
    };
    TableElement.ATTRS = {
        tableSummary: {
            value: ""
        },

        tableCaption: {
            value: ""
        },

        tableColumns: {
            value: []
        },

        statisticTable: {
            value: null
        },

        tableDate: {
            value: []
        }
    }
    Y.extend(TableElement, HtmlElement, {
        render: function () {
            var instance = this,
                host = instance.get('host'), wrapper, wrapperTable

            wrapperTable = Y.Node.create('<div class="statistics-table"> </div>');
            wrapper = Y.Node.create('<div class="form-group table-input"></div>');

            var simpleTable = new Y.DataTable({
                columns: instance.get('tableColumns'),
                data: [
                    instance.get('tableDate')
                ],
                summary: instance.get('tableSummary'),
                caption: instance.get('tableCaption')
            });

            instance.set('statisticTable', simpleTable)
            simpleTable.render(wrapperTable);
            wrapper.append(wrapperTable);
            return simpleTable;
        },
        initializer: function () {
            var instance = this;
            instance.after("valueChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('value', e.newVal);
                }
            });
            instance.after("placeholderChange", function (e) {
                var host = instance.get('host');
                if (host) {
                    host.setAttribute('placeholder', e.newValue);
                }
            });
        },
        addAfterRenderEvents: function () {
            this.get('statisticTable').syncUI();
        }
    });
    Y.TableElement = TableElement;


    /**
     * This class will generate an textarea element
     *
     *      new TextAreaElement({
     *          label: 'My input label',
     *          value: 'Hello input element!'
     *      });
     *
     * will render:
     *
     *      <div class="form-group">
     *          <label>My input label</label>
     *          <textarea value="Hello input element!" />
     *      </div>
     *
     * @param cfg
     * @constructor
     * @class TextAreaElement
     * @extends HtmlElement
     */
    var TextAreaElement = function (cfg) {
        TextAreaElement.superclass.constructor.apply(this, arguments);
    }
    TextAreaElement.NAME = 'TextAreaElement';
    TextAreaElement.NS = 'TextAreaElement';
    TextAreaElement.ATTRS = {
        /**
         * Defines the placeholder attribute for this input
         *
         * @attribute placeholder
         * @type {String}
         * @default ''
         */
        placeholder: {
            value: ''
        },


        /**
         * sets the type attribute value as 'input'
         *
         * @attribute element
         * @type {String}
         * @default ''
         * @readOnly
         */
        element: {
            setter: function (val, name) {
                // readOnly
            },
            value: 'textarea'
        },

        /**
         * sets the number of columns to be displayed
         *
         * @attribute element
         * @type {String}
         * @default ''
         * @readOnly
         */
        cols: {
            setter: function (val, name) {
                // readOnly
            },
            value: '100'
        },

        /**
         * sets the number of rows
         *
         * @attribute element
         * @type {String}
         * @default ''
         * @readOnly
         */
        rows: {
            setter: function (val, name) {
                // readOnly
            },
            value: '5'
        },

        /**
         * If set to true, this element is rendered as disabled
         *
         * @attribute disabled
         * @type {Boolean}
         * @default false
         */
        disabled: {
            value: false
        }
    };
    Y.extend(TextAreaElement, InputElement, {});
    Y.TextAreaElement = TextAreaElement;


    /**
     * Renders an editable table control
     *
     * @param cfg
     * @constructor
     * @class MetadataEditInTableElement
     * @extends PanelElement
     */
    var MetadataEditInTableElement = function (cfg) {
        MetadataEditInTableElement.superclass.constructor.apply(this, arguments);
    };

    MetadataEditInTableElement.ATTRS = {
        /**
         * Contains an array of primitives or objects of type {key: 'key', value: 'value'}
         * These options are populated in the table
         *
         * @attribute options
         * @type {Array}
         * @default []
         */
        options: {
            value: []
        },
        displayOrderButton: {
            value: true
        }
    };

    Y.extend(MetadataEditInTableElement, PanelElement, {
        initializer: function () {
            var instance = this,
                modelInstance = instance.get("modelInstance"),
                name = instance.get('name'),
                children = [], i
            ;

            if (!instance.get('cssClass')) {
                instance.set('cssClass', '');
            }
            var cssClass = instance.get('cssClass');
            cssClass += ' metadataEditInTableElement';
            instance.set('cssClass', cssClass);

            var innerChildren = instance.generateChildren(null);
            innerChildren.push(instance.getMetadataShareThisSelector());

            var displayOrderButton = instance.get('displayOrderButton');
            if (displayOrderButton) {
                innerChildren.push(instance.getMetadataOrderThisSelector());
            }
            children.push(new Y.HtmlElement({
                children: innerChildren
            }));

            instance.set('children', children);
        },

        getMetadataShareThisSelector: function () {
            var instance = this,
                modelInstance = instance.get('modelInstance');
            var selector = new Y.HtmlElement({
                cssClass: 'form-group pfrm col-md-12',
                children: [
                    new Y.CheckboxElement({
                        label: modelInstance.t('baseWidgetList.sharethis'),
                        wrapperCssClass: 'col-md-4 check',
                        checked: (modelInstance.getAttrs().showSharePublicationButton ? true : false),
                        modelInstance: modelInstance,
                        id: 'showSharePublicationButton',
                        onClick: function () {
                            var showSharePublicationButton = !modelInstance.getAttrs().showSharePublicationButton;
                            if (showSharePublicationButton) {
                                modelInstance.set("showSharePublicationButton", true);
                            }
                            else {
                                modelInstance.set("showSharePublicationButton", false);
                            }
                            modelInstance.updateMetadataAppearanceListControlButton('shareButton', showSharePublicationButton, 'left');
                        }
                    })
                ]
            });

            return selector;
        },

        getMetadataOrderThisSelector: function () {
            var instance = this,
                modelInstance = instance.get('modelInstance');
            var selector = new Y.HtmlElement({
                cssClass: 'form-group pfrm col-md-12',
                children: [
                    new Y.CheckboxElement({
                        label: modelInstance.t('baseWidgetList.orderthis'),
                        wrapperCssClass: 'col-md-4 check',
                        checked: (modelInstance.getAttrs().showOrderPublicationButton ? true : false),
                        modelInstance: modelInstance,
                        id: 'showOrderPublicationButton',
                        onClick: function () {
                            var showOrderPublicationButton = !modelInstance.getAttrs().showOrderPublicationButton;
                            if (showOrderPublicationButton) {
                                modelInstance.set("showOrderPublicationButton", true);
                            }
                            else {
                                modelInstance.set("showOrderPublicationButton", false);
                            }
                            modelInstance.updateMetadataAppearanceListControlButton('orderButton', showOrderPublicationButton, 'left');
                        }
                    })
                ]
            });

            return selector;

        },

        //postRender: function (elem) {
        generateChildren: function (elem) {
            var instance = this,
                attrs = instance.getAttrs(),
                wrapper, i,
                modelInstance = instance.get('modelInstance');
            var options = instance.get('options');
            //var host = instance.get('host');
            // var node = host.one('.elementsMetadataHtmlPanel');
            var children = [];
            var tableHeader = new Y.HtmlElement({
                cssClass: 'panel-heading row',
                children: [
                    new Y.HtmlElement({
                        label: modelInstance.t('baseWidgetList.elements'),
                        wrapperCssClass: 'col-md-3'
                    }),
                    new Y.HtmlElement({
                        label: modelInstance.t('baseWidgetList.labels'),
                        wrapperCssClass: 'col-md-3'
                    }),
                    new Y.HtmlElement({
                        label: modelInstance.t('baseWidgetList.maximumNumberOfChars'),
                        wrapperCssClass: 'col-md-6'
                    }),
                ]
            });
            //tableHeader.render(node);
            children.push(tableHeader);

            for (i = 0; i < options.length; i++) {
                var elementsColumnElem = instance.generateMetadataObjectType(modelInstance,
                    options[i].type,
                    options[i].key);
                if (elementsColumnElem) {
                    //elementsColumnElem.render(node);
                    children.push(elementsColumnElem);
                }
            }
            return children;
        },
        getDisplayedMetadataObject: function (modelInstance, key) {
            var displayedMetadataObjList = modelInstance.get(METADATA_SAVED_OBJS);
            if (displayedMetadataObjList) {
                for (i = 0; i < displayedMetadataObjList.length; i++) {
                    if (displayedMetadataObjList[i].key == key) {
                        return displayedMetadataObjList[i];
                    }
                }
            }
            return null;
        },
        updateDisplayedMetadataShowLabel: function (modelInstance, key, showLabel) {
            var selectedMetadataObject = this.getDisplayedMetadataObject(modelInstance, key);
            if (selectedMetadataObject) {
                selectedMetadataObject.showLabel = showLabel;
            }
        },
        updateDisplayedMetadataDisplayedLength: function (modelInstance, key, displayLength) {
            var selectedMetadataObject = this.getDisplayedMetadataObject(modelInstance, key);
            if (selectedMetadataObject) {
                if (displayLength) {
                    selectedMetadataObject.maxLength = displayLength;
                }
                else if (selectedMetadataObject.maxLength) {
                    delete selectedMetadataObject.maxLength;
                }
            }
        },
        updateDisplayedMetadataDisplayedMaxItems: function (modelInstance, key, maxItems) {
            var selectedMetadataObject = this.getDisplayedMetadataObject(modelInstance, key);
            if (selectedMetadataObject) {
                if (maxItems) {
                    selectedMetadataObject.maxItems = maxItems;
                }
                else if (selectedMetadataObject.maxItems) {
                    delete selectedMetadataObject.maxItems;
                }
            }
        },
        updateDisplayedMetadataFormatType: function (modelInstance, type, key, formatType) {
            var selectedMetadataObject = this.getDisplayedMetadataObject(modelInstance, key);
            if (selectedMetadataObject) {
                var allNodeList = Y.all('#' + modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + ELEMENT_TYPE.RADIO);
                if (allNodeList) {
                    var nodeIdx = 0;
                    for (nodeIdx = 0; nodeIdx < allNodeList.size(); nodeIdx++) {
                        var formatsRadioCtrl = allNodeList.item(nodeIdx);
                        if (formatsRadioCtrl && formatsRadioCtrl.get('checked') == true) {
                            selectedMetadataObject.metadataFieldType = formatsRadioCtrl.get('value');
                            break;
                        }
                    }
                }
            }
        },
        removeDisplayedMetadataElement: function (modelInstance, key) {
            var index = -1;
            var displayedMetadataObjList = modelInstance.get(METADATA_SAVED_OBJS);
            for (i = 0; i < displayedMetadataObjList.length; i++) {
                if (displayedMetadataObjList[i].key == key) {
                    index = i;
                    break;
                }
            }
            if (index > -1) {
                displayedMetadataObjList.splice(index, 1);
            }
        },
        addDisplayedMetadataElement: function (modelInstance, key, type) {
            var selectedMetadataObject = this.getDisplayedMetadataObject(modelInstance, key);
            if (selectedMetadataObject) {
                return;
            }
            var newMetadataObject = {
                key: key,
                metadataFieldType: type
            };
            if (type == FIELDTYPE.TEXT) {
                var showLabelCtrl = Y.one('#' + modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + ELEMENT_TYPE.CHECKBOX);
                var showLabel = false;
                if (showLabelCtrl) {
                    showLabel = showLabelCtrl.get('checked') == true;
                }
                newMetadataObject.showLabel = showLabel;

                var maxLabelCtrl = Y.one('#' + modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + ELEMENT_TYPE.INPUT);
                if (maxLabelCtrl && maxLabelCtrl.get('value')) {
                    newMetadataObject.maxLength = maxLabelCtrl.get('value');
                }

                var maxItemsCtrl = Y.one('#' + modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + "maxItems");
                if (maxItemsCtrl && maxItemsCtrl.get('value')) {
                    newMetadataObject.maxItems = maxItemsCtrl.get('value');
                }
            }
            if (type == FIELDTYPE.ICON) {
                var formatsRadioCtrl = Y.one('#' + modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + ELEMENT_TYPE.RADIO);
                if (formatsRadioCtrl) {
                    newMetadataObject.metadataFieldType = formatsRadioCtrl.get('value');
                }
            }

            modelInstance.get(METADATA_SAVED_OBJS).push(newMetadataObject);
        },
        postRender: function (elem) {
            /*  var instance = this;
              modelInstance = instance.get('modelInstance');
              modelInstance.updateMetadataAppearanceListNew();*/
            return elem;
        },

        generateMetadataObjectType: function (modelInstance, type, key) {
            var instance = this, genObj = null;
            var selectedMetadataObject = this.getDisplayedMetadataObject(modelInstance, key);
            var showLabelValue = false;
            var isSelected = false;
            var maxLength = '';
            var maxItems = '';
            if (selectedMetadataObject) {
                isSelected = true;
                showLabelValue = selectedMetadataObject.showLabel;
                maxLength = selectedMetadataObject.maxLength;
                maxItems = selectedMetadataObject.maxItems;
            }
            var children = [new Y.CheckboxElement({
                id: modelInstance.get(ELEM_ATTR.NAMESPACE) + '_edt_' + key + '_' + ELEMENT_TYPE.CHECKBOX,
                label: modelInstance.t('baseWidgetList.' + key),
                value: key,
                wrapperCssClass: 'col-md-3 check',
                checked: isSelected,
                modelInstance: modelInstance,
                onChange: function (e) {
                    //Call for updating the object value/status in the object list
                    var selectedCheckBox = e.target;
                    if (selectedCheckBox.get('checked') === true) {
                        instance.addDisplayedMetadataElement(modelInstance, key, type);
                    }
                    else {
                        instance.removeDisplayedMetadataElement(modelInstance, key);
                    }
                    modelInstance.updateMetadataAppearanceListNew();
                }
            })];
            children.push();
            if (type == FIELDTYPE.TEXT) {
                children.push(
                    new Y.CheckboxElement({
                        id: modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + ELEMENT_TYPE.CHECKBOX,
                        label: modelInstance.t('searchResult.checkbox.showlabels') + ':' + modelInstance.t('baseWidgetList.' + key),
                        wrapperCssClass: 'col-md-3 check',
                        checked: showLabelValue,
                        modelInstance: modelInstance,
                        onChange: function (e) {
                            //Call for updating the object value/status in the object list
                            instance.updateDisplayedMetadataShowLabel(modelInstance, key, e.target.get('checked'));
                        }
                    }));
                children.push(new Y.InputElement({
                    id: modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + ELEMENT_TYPE.INPUT,
                    label: '',
                    wrapperCssClass: 'col-md-2 max-char',
                    modelInstance: modelInstance,
                    value: maxLength,
                    onChange: function (e) {
                        var value = e.target.get('value');
                        if (!isNaN(value)) {
                            //Call for updating the object value/status in the object list
                            e.target.setStyle("border", "#bbbbbb 1px solid");
                        }
                        else {
                            e.target.setStyle("border", "#FF0000 2px solid");
                        }
                        if (value) {
                            var maxSubjectsSelect = e.target.get('parentNode').get('parentNode').one('.max-items select');
                            if (maxSubjectsSelect) {
                                maxSubjectsSelect.set('value', '');
                            }
                            instance.updateDisplayedMetadataDisplayedMaxItems(modelInstance, key, undefined);
                        }
                        instance.updateDisplayedMetadataDisplayedLength(modelInstance, key, value);
                    }
                }));
                if (key == 'subjects') {
                    children.push(new Y.SelectBoxElement({
                        wrapperCssClass: 'col-md-4 max-items',
                        id: modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + 'maxItems',
                        name: modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + 'maxItems',
                        modelInstance: modelInstance,
                        label: modelInstance.t('baseWidgetList.maxNumberOfSubjects'),
                        options: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
                        defaultSelectValue: maxItems,
                        onChange: function (e) {
                            var value = e.target.get('value');
                            if (value) {
                                var maxCharInput = e.target.get('parentNode').get('parentNode').one('.max-char input');
                                if (maxCharInput) {
                                    maxCharInput.set('value', '');
                                }
                                instance.updateDisplayedMetadataDisplayedLength(modelInstance, key, undefined);
                            }
                            instance.updateDisplayedMetadataDisplayedMaxItems(modelInstance, key, value);
                        }
                    }));
                }
            }

            if (type == FIELDTYPE.ICON) {
                var isIconSelected = true;

                if (selectedMetadataObject) {
                    if (selectedMetadataObject.metadataFieldType === FIELDTYPE.TEXT) {
                        isIconSelected = false;
                    }
                }
                children.push(new Y.RadioElement({
                    id: modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + ELEMENT_TYPE.RADIO,
                    label: modelInstance.t('searchResult.format.icon'),
                    checked: isIconSelected,
                    wrapperCssClass: 'col-md-1 px-0',
                    name: modelInstance.get(ELEM_ATTR.NAMESPACE) + '_' + key + '_' + ELEMENT_TYPE.RADIO,
                    modelInstance: instance,
                    value: FIELDTYPE.ICON,
                    onChange: function (e) {
                        //Call for updating the object value/status in the object list
                        instance.updateDisplayedMetadataFormatType(modelInstance, type, key, FIELDTYPE.ICON);
                    }
                }));
                children.push(new Y.RadioElement({
                    id: modelInstance.get(ELEM_ATTR.NAMESPACE) + type + '_edt_' + key + '_' + ELEMENT_TYPE.RADIO,
                    label: modelInstance.t('searchResult.format.text'),
                    wrapperCssClass: 'col-md-1 px-0',
                    checked: !isIconSelected,
                    name: modelInstance.get(ELEM_ATTR.NAMESPACE) + '_' + key + '_' + ELEMENT_TYPE.RADIO,
                    modelInstance: modelInstance,
                    value: FIELDTYPE.TEXT,
                    onChange: function (e) {
                        //Call for updating the object value/status in the object list
                        instance.updateDisplayedMetadataFormatType(modelInstance, type, key, FIELDTYPE.TEXT);
                    }
                }));
                children.push(new Y.HtmlElement({
                    label: modelInstance.t('searchResult.formats'),
                    wrapperCssClass: 'widgetFormats',
                    cssClass: 'form-inline',
                    children: modelInstance.getFormatOptionList()
                }));
            }

            // Empty HTML object.
            if (type == FIELDTYPE.IMAGE) {
                //nothing to be done
                children.push(
                    modelInstance.getUseDefaultThumbnailImageSelector()
                );
            }

            genObj = new Y.HtmlElement({
                value: key,
                wrapperCssClass: 'col-md-12',
                id: type,
                children: children
            });

            return genObj;
        }


    });
    Y.MetadataEditInTableElement = MetadataEditInTableElement;


}, 'portalop-2014.05.28-17-20', {
    requires: [
        'node',
        'base-build',
        'plugin',
        'attribute-base',
        'io-base',
        'history-hash',
        'wizardTools',
        'autocomplete',
        'aui-datepicker',
        'aui-tabview',
        'aui-popover',
        'tabview',
        'datatable',
        'datatable-paginator',
        'datatype-number',
        'panel'
    ]
});
/**
 * This module keeps the abstract class BaseWidgetList, further extended by PublicationViewWidgetWizard and
 * SearchResultWidgetWizard
 *
 * @module baseWidgetList
 * @requires node
 * @requires base-build
 * @requires plugin
 * @requires attribute-base
 * @requires wizardTools
 * @requires formWidget
 * @requires dd-constrain
 * @requires dd-proxy
 * @requires dd-drop
 */
YUI.add('baseWidgetList', function (Y) {

    var
            /**
             * Static constant to refer field 'layoutStyle'
             *
             * @property FIELD_LAYOUT_STYLE
             * @type String
             * @static
             * @final
             */
            FIELD_LAYOUT_STYLE = 'layoutStyle',

            /**
             * Static constant to refer field 'selectedMetadata'
             *
             * @property FIELD_SELECTED_METADATA
             * @type String
             * @static
             * @final
             */
            FIELD_SELECTED_METADATA = 'selectedMetadata',


            FIELD_SHARE_THIS = 'showSharePublicationButton',
            FIELD_ORDER_THIS = 'showOrderPublicationButton',
            FIELD_VIEW_THIS = 'showViewPublicationButton',

            FIELD_USE_DEFAULT_THUMBNAIL_IMAGE = 'useDefaultThumbnailImage',
            FIELD_SHOW_ONLY_SELECTED_LANGUAGE_PUBLICATIONS = 'showOnlySelectedLanguagePublications',


            /**
             * Object used in string replacement on function calls.
             * Can be extended in future with other attributes.
             * @type {{CHECKBOX: string, INPUT: string, RADIO: string}}
             * @static
             * @final
             */

            ELEMENT_TYPE = {
                CHECKBOX: 'CheckboxElement',
                INPUT: 'InputElement',
                RADIO: 'RadioElement'
            },

            /**
             * Object used to set status of elements.
             * Can be extended in the future.
             * @type {{CHECKBOX_STATUS: string, VALUE: string, NAMESPACE: string}}
             * @static
             * @final
             */
            ELEM_ATTR = {
                CHECKBOX_STATUS: 'checked',
                VALUE: 'value',
                NAMESPACE: 'namespace'
            },

            /**
             * Static constant to refer field 'layout'
             *
             * @property FIELD_LAYOUT
             * @type String
             * @static
             * @final
             */
            FIELD_LAYOUT = 'layout',

            /**
             * Static constant to refer field 'layoutFlexibleRatio'
             *
             * @property FIELD_LAYOUT_FLEXIBLE_RATIO
             * @type String
             * @static
             * @final
             */
            FIELD_LAYOUT_FLEXIBLE_RATIO = 'layoutFlexibleRatio',
            /**
             * Static constant to refer field widgetTemplateId
             * @type {string}
             */
            FIELD_WIDGET_TEMPLATE_ID = 'widgetTemplateId',

            /**
             * Static constant to refer field 'endpoint'
             *
             * @property FIELD_ENDPOINT
             * @type String
             * @static
             * @final
             */
            FIELD_ENDPOINT = 'endpoint',

            /**
             * Static constant to refer field 'layoutMetadata'
             *
             * @property FIELD_LAYOUT_METADATA
             * @type String
             * @static
             * @final
             */
            FIELD_LAYOUT_METADATA = 'layoutMetadata',

            /**
             * Static constant to refer field 'layoutColumns'
             *
             * @property FIELD_COLUMNS
             * @type String
             * @static
             * @final
             */
            FIELD_COLUMNS = 'layoutColumns',

            /**
             * Static constant to refer field 'layoutRows'
             *
             * @property FIELD_ROWS
             * @type String
             * @static
             * @final
             */
            FIELD_ROWS = 'layoutRows',

            /**
             * Static constant defines a value for field 'layoutStyle'
             *
             * @property STYLE_PAGINATED
             * @type String
             * @static
             * @final
             */
            STYLE_PAGINATED = 'paginated',

            /**
             * Static constant defines a value for field 'layoutStyle'
             *
             * @property STYLE_SLIDE_SHOW
             * @type String
             * @static
             * @final
             */
            STYLE_SLIDE_SHOW = 'slideShow',

            /**
             * Static constant defines a name for field 'slideShowNumberSlides'
             *
             * @property FIELD_SLIDE_SHOW_NUMBER_SLIDES
             * @type String
             * @static
             * @final
             */
            FIELD_SLIDE_SHOW_NUMBER_SLIDES = 'slideShowNumberSlides',

            /**
             * Static constant defines a name for field 'slideShowTiming'
             *
             * @property FIELD_SLIDE_SHOW_TIMING
             * @type String
             * @static
             * @final
             */
            FIELD_SLIDE_SHOW_TIMING = 'slideShowTiming',

            /**
             * Static constant defines a name for field 'slideShowEffect'
             *
             * @property FIELD_SLIDE_SHOW_EFFECT
             * @type String
             * @static
             * @final
             */
            FIELD_SLIDE_SHOW_EFFECT = 'slideShowEffect',

            /**
             * Static constant defines a name for field 'slideShowControls'
             *
             * @property FIELD_SLIDE_SHOW_CONTROLS
             * @type String
             * @static
             * @final
             */
            FIELD_SLIDE_SHOW_CONTROLS = 'slideShowControls',

            /**
             * Static constant defines a name for field 'slideShowColumns'
             *
             * @property FIELD_SLIDE_SHOW_COLUMNS
             * @type String
             * @static
             * @final
             */
            FIELD_SLIDE_SHOW_COLUMNS = 'slideShowColumns',

            /**
             * Static constant defines a value for field 'listStyleSlideShowNavigation', not yet implemented
             *
             * @property NAVIGATION_ARROWS
             * @type String
             * @static
             * @final
             */
            NAVIGATION_ARROWS = 'arrows',

            /**
             * Static constant defines a value for field 'listStyleSlideShowNavigation', not yet implemented
             *
             * @property NAVIGATION_DOTS
             * @type String
             * @static
             * @final
             */
            NAVIGATION_DOTS = 'dots',

            /**
             *  Object used to set the MetaTags field types.
             *  Do not modify, MetaTags types are predefined.
             * @type {{TEXT: string, ICON: string, IMAGE: string}}
             * @static
             * @final
             */

            FIELDTYPE = {TEXT: 'TEXT', ICON: 'ICON', IMAGE: 'IMAGE'},

            METADATA_SELECT = [{
                value: 'Select',
                key: 'select',
                type: null
            }],
            /**
             * Static constant defines the available metadata, to be used in metadata selection
             *
             * @property METADATA
             * @type Array
             * @static
             * @final
             */
            METADATA = [{
                value: 'Title',
                key: 'title',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Subtitle',
                key: 'subtitle',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Abstract',
                key: 'abstract',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Date',
                key: 'publishing_date',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Author',
                key: 'authors',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Subject',
                key: 'subjects',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Format',
                key: 'available_formats',
                type: FIELDTYPE.ICON
            }, {
                value: 'Thumbnail',
                key: 'thumbnail',
                type: FIELDTYPE.IMAGE
            }, {
                value: 'Description',
                key: 'description',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Published',
                key: 'published_date',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Submission deadline',
                key: 'submission_deadline',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Status',
                key: 'status',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Buyer',
                key: 'buyer',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Estimated contract value',
                key: 'estimated_contract_value',
                type: FIELDTYPE.TEXT
            }, {
                value: 'CPV Code',
                key: 'business_sector ',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Place of performance (NUTS)',
                key: 'nuts',
                type: FIELDTYPE.TEXT
            }],

            /**
             * Keeps a list of options to be displayed in the widget
             *
             * @property OPTIONS
             * @type {Array} of elements of type {key: 'title', disabled: false}
             * @static
             * @final
             */
            OPTIONS = [
                {key: 'title', disabled: false},
                {key: 'nrOfResults', disabled: false},
                {key: 'nrOfRows', disabled: false},
                {key: 'navigation', disabled: false},
                {key: 'rss', disabled: false},
                {key: 'alert', disabled: false},
                {key: 'sortBy', disabled: false},
                {key: 'filters', disabled: false}
            ],

            /**
             * Keeps a list of selected format otions for returned results
             * @type {{key: string, disabled: boolean}[]}
             */
            FORMAT_OPTIONS = [
                {key: 'pdf', disabled: false},
                {key: 'epub', disabled: false},
                {key: 'html', disabled: false},
                {key: 'doc', disabled: false},
                {key: 'mobile', disabled: false}
            ],

            /**
             * Basic defaults for appearance settings
             * @type {{fontSize: string, marginWidth: string, paddingWidth: string, fontColor: string, backgroundColor: string, borderColor: string, height: number, width: number}}
             */
            BASIC_APPEARANCE_DFAULTS = {
                fontSize: '12 px',
                marginWidth: '2 px',
                paddingWidth: '2 px',
                fontColor: '#2873eb',
                backgroundColor: '#ffffff',
                borderColor: '#d3d3d3',
                height: '0',
                fontFamily: 'Arial',
                borderWidth: 1,
                width: '0',
                maxWidth: '',
                minWidth: '0',
                minHeight: '0'
            },

            /**
             * advanced appearance url for ajax request
             * @type {string}
             */
            ADVANCED_APPEARANCE_URL = '/o/opportal-service/widget/appearance',

            /**
             * basic appearance url for ajax request
             * @type {string}
             */
            BASIC_APPEARANCE_URL = '/o/opportal-service/widget/appearanceObject',

            /**
             * static fields defines an array of available layouts
             *
             * @property LAYOUTS
             * @type Array
             * @static
             * @final
             */
            LAYOUTS = ['l1', 'l11', 'l12', 'l21', 'l11f'],

            /**
             * Restricts the max selectable columns in paginated layout style
             *
             * @property RESTRICTION_MAX_COLUMNS
             * @type int
             * @static
             * @final
             */
            RESTRICTION_MAX_COLUMNS = 6,

            /**
             * Restricts the max selectable rows in paginated layout style
             *
             * @property RESTRICTION_MAX_ROWS
             * @type int
             * @static
             * @final
             */
            RESTRICTION_MAX_ROWS = 25,

            /**
             * Numer of slide show slides
             * @type {number}
             */

            NUMBER_OF_SLIDES = 20,

            /**
             * Slide show timing.
             * @type {number}
             */

            SLIDE_SHOW_TIMING = 6,

            /**
             * Numer of slide show slides
             * @type {number}
             */

            NUMBER_OF_COLUMNS = 5,

            /**
             * Restricts the max selectable items per slide in SlideShow layout style
             *
             * @property RESTRICTION_MAX_ITEMS_PER_SLIDE
             * @type int
             * @static
             * @final
             */
            RESTRICTION_MAX_ITEMS_PER_SLIDE = 5,


            /**
             * Constant variable for Drag'n'Drop implementation, that allows the boxes to be moved in first row
             *
             * @property goingUp
             * @type boolean
             * @static
             */
            goingUp = false,

            metaDataAppearanceObjs = [],
            APPEARANCE_BASIC_PREVIEW_MIN_HEIGHT = 'minHeight',
            APPEARANCE_BASIC_PREVIEW_MIN_WIDTH = 'minWidth',
            APPEARANCE_BASIC_PREVIEW_FONT_FAMILY = 'fontFamily',
            APPEARANCE_BASIC_PREVIEW_BACKGROUND_COLOR = 'backgroundColor',
            APPEARANCE_BASIC_PREVIEW_BORDER_WIDTH = 'borderWidth',
            APPEARANCE_BASIC_PREVIEW_BORDER_COLOR = 'borderColor',

            APPEARANCE_BASIC_PREVIEW_METADATA = 'previewMetadata',
            APPEARANCE_BASIC_PREVIEW_TITLE_H = 'previewHitleH',
            APPEARANCE_BASIC_PREVIEW_FONT_SIZE = 'previewFontSize',
            APPEARANCE_BASIC_PREVIEW_FONT_COLOR = 'previewFontColor',
            APPEARANCE_BASIC_PREVIEW_MARGIN_WIDTH = 'previewMarginWidth',
            APPEARANCE_BASIC_PREVIEW_PADDING_WIDTH = 'previewPaddingWidth',
            APPEARANCE_BASIC_PREVIEW_MAX_WIDTH = 'previewMaxWidth',
            FIELD_ADVANCED_SET_APPEARANCE = 'advancedAppearance',
            APPEARANCE_BASIC_DISPLAY = 'widgetAppearance',
            APPEARANCE_BASIC_DISPLAY_OBJ_LIST = 'metadataAppearanceList',

            ADVANCED_APPEARANCE_METADATA = 'advancedAppearanceMetadata',
            ADVANCED_APPEARANCE_PROPERTY = 'advancedAppearanceProperty',
            APPEARANCE_BASIC_PREVIEW_HEIGHT = 'height',
            APPEARANCE_BASIC_PREVIEW_WIDTH = 'width',


            appearanceMetadata = {
                metadata: '',
                htmlElement: '',
                fontSize: 0,
                fontColor: '',
                margin: 0,
                padding: 0
            },

            /**
             * Static constant to refer field 'header'
             *
             * @property FIELD_HEADER
             * @type String
             * @static
             * @final
             */
            FIELD_HEADER = 'header',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_FOOTER
             * @type String
             * @static
             * @final
             */
            FIELD_FOOTER = 'footer',

            /**
             * Static constant defines a name for field 'enabledSortByCriteria'
             *
             * @property FIELD_ENABLED_SORT_BY_CRITERIA
             * @type String
             * @static
             * @final
             */
            FIELD_ENABLED_SORT_BY_CRITERIA = 'enabledSortByCriteria',
            /**
             * List of strings containing the enabled filters for this widget
             * @property FIELD_ENABLED_FILTERS
             * @type String
             * static constant
             *
             */
            FIELD_ENABLED_FILTERS = 'enabledFilters',
            /**FIELD_ENABLED_TOPICS - list of strings containing enabled topics
             * @property
             * @type {string}
             */
            FIELD_ENABLED_TOPICS = 'enabledTopics',

            /**
             * Static constant to refer field 'format'
             *
             * @property FIELD_FOOTER
             * @type String
             * @static
             * @final
             */
            FIELD_FORMAT_OPTIONS = 'resultFormats',

            FIELD_RESULTS_PAGE = 'resultsPage',
            FIELD_TARGET_PAGE = 'targetPage',
            RESULTS_PAGE_EU_LAW = 'a',
            RESULTS_PAGE_OWN = 'b',

            currentAppearanceOption = '',
            basicAppearance = '',
            currentMetaOtion = '',
            widgetAppearance = {},
            metadataAppearanceList = [],
            METADATA_SELECTION_OBJS = [],
            METADATA_SAVED_OBJS = 'selectedMetaDataFieldType',
            slideShowLayout = {},
            appearanceMetadataObjectsInstanceList = [],
            CLEAR_CACHE = 'clearCache',


            /**
             * Used in display appearance methods         *
             * @type {string[]}
             */

            fontList = ['Arial', 'Helvetica', 'Sans-Serif'],
            borderList = ["0", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
            hElemList = ['', 'p', 'i', 'b', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'H7'],

            /**
             * Constant variable for Drag'n'Drop implementation, that allows the boxes to be moved in first row
             *
             * @property lastY
             * @type boolean
             * @static
             */
            lastY = 0;

    /**
     * This is an abstract class, further extended by {{#crossLink 'PublicationViewWidgetWizard'}}{{/crossLink}} and {{#crossLink 'SearchResultWidgetWizard'}}{{/crossLink}}
     *
     * @param cfg
     * @class BaseWidgetList
     * @constructor
     * @extends AbstractWizard
     */
    function BaseWidgetList(cfg) {
        BaseWidgetList.superclass.constructor.apply(this, arguments);
    }

    BaseWidgetList.NAME = 'BaseWidgetList';
    BaseWidgetList.NS = 'BaseWidgetList';

    BaseWidgetList.ATTRS = {

        /**
         * This attribute will keep the widget title, that will represent an object with language labels at
         *
         * @attribute title
         * @type Object
         * @default {}
         */
        title: {
            value: {}
        },

        /**
         * This attribute will keep the metadata selected by the user, to be displayed in the widget {{#crossLink 'BaseWidgetList/METADATA:property'}}{{/crossLink}}
         *
         * @attribute selectedMetadata
         * @type Array
         * @default []
         */
        selectedMetadata: {
            value: []
        },

        /**
         * This attribute will keep the selected layout {{#crossLink 'BaseWidgetList/LAYOUTS:property'}}{{/crossLink}}
         *
         * @attribute layout
         * @type String
         * @default ''
         */
        layout: {
            value: ''
        },

        layoutFlexibleRatio: {
            value: '6-6'
        },

        /**
         * This attribute will keep the search type
         *
         * @attribute endpoint
         * @type String
         * @default 'IDOL'
         */
        endpoint: {
            value: ''
        },

        /**
         * This attribute will keep arrays of metadata id's.
         * For example, for layout value l11, this will be an array of 2 elements:
         *
         *      instance.set('layoutMetadata', [
         *              ['title', 'publishing_date'],
         *              [authors]
         *          ]);
         *
         *  meaning that on col 1 there is 'title' and 'publishing_date', and on col 2 there is 'authors'
         *
         * @attribute layoutMetadata
         * @type Array
         * @default []
         */
        layoutMetadata: {
            value: []
        },

        /**
         * This attribute keeps the selected display style of results, {{#crossLink 'BaseWidgetList/STYLE_PAGINATED:property'}}{{/crossLink}} or {{#crossLink 'BaseWidgetList/STYLE_SLIDE_SHOW:property'}}{{/crossLink}}
         * @attribute layoutStyle
         * @type String
         * @default 'paginated'
         */
        layoutStyle: {
            value: STYLE_PAGINATED,
            validator: function (val, name) {
                return (val == STYLE_SLIDE_SHOW || val == STYLE_PAGINATED);
            }
        },

        /**
         * This attribute keeps the number of the result is displayed
         * @attribute layoutColumns
         * @type int
         * @default 1
         */
        layoutColumns: {
            value: 1,
            validator: function (val, name) {
                Y.Lang.isNumber(val) || (val = parseInt(val));
                return (Y.Lang.isValue(val) && val > 0 && val <= RESTRICTION_MAX_COLUMNS);
            }
        },

        /**
         * This attribute keeps the number of rows the result is displayed.
         *
         * @attribute layoutRows
         * @type int
         * @default 1
         */
        layoutRows: {
            value: 1,
            validator: function (val, name) {
                Y.Lang.isNumber(val) || (val = parseInt(val));
                return (Y.Lang.isValue(val) && val > 0 && val <= RESTRICTION_MAX_ROWS);
            }
        },

        /**
         * This attribute keeps the number of items per SlideShow slide.
         *
         * @attribute listStyleSlideShowItemsPerSlide
         * @type int
         * @default 1
         */
        listStyleSlideShowItemsPerSlide: {
            value: 1,
            validator: function (val, name) {
                return (Y.Lang.isNumber(val) && val > 0 && val <= RESTRICTION_MAX_ITEMS_PER_SLIDE);
            }
        },

        metadataAppearanceList: {
            value: []
        },

        widgetAppearance: {
            value: {}
        },

        advancedAppearance: {
            value: ''
        },

        slideShowNumberSlides: {
            value: 1
        },

        slideShowTiming: {
            value: 1
        },

        slideShowEffect: {
            value: 'basic'
        },

        slideShowControls: {
            value: 'bullets'
        },

        enabledSortByCriteria: {
            value: []
        },
        enabledFilters: {
            value: []
        },

        enabledTopics:{
            value:{}
        },

        /**
         * This attribute keeps the navigation style of the SlideShow
         * {{#crossLink 'BaseWidgetList/NAVIGATION_ARROWS:property'}}{{/crossLink}} or {{#crossLink 'BaseWidgetList/NAVIGATION_DOTS:property'}}{{/crossLink}}
         *
         * @attribute listStyleSlideShowNavigation
         * @type String
         * @default 1
         */
        listStyleSlideShowNavigation: {
            value: NAVIGATION_ARROWS,
            validator: function (val, name) {
                return (val == NAVIGATION_ARROWS || val == NAVIGATION_DOTS);
            }
        },

        /**
         * Share this
         */
        showSharePublicationButton: {
            value: false
        },
        showOrderPublicationButton: {
            value: false
        },
        showViewPublicationButton: {
            value: false
        },

        slideShowLayout: {
            value: null
        },

        /**
         * Use default thumbnail image if no thumbnail available
         */
        useDefaultThumbnailImage: {
            value: true
        },

        /**
         * Show only publications in browsing language
         */
        showOnlySelectedLanguagePublications: {
            value: true
        },


        /*
         * Target page
         */
        resultsPage: {
            value: RESULTS_PAGE_EU_LAW
        },
        targetPage: {
            value: ''
        },
        /**
         *  metadata selection refactoring
         *  array of objects containing selected metadata
         *  each object has following propertes
         *  key - code of metadata attribute
         *  metadataFieldType - type of metadata attribute
         *  showLabel - value of showLabel checkbox
         *  maxLength - number of characters to be displayed
         *  maxItems - number of items to be displayed
         *  formatsType - for formats metadata specify if they will be displayed as ICON or TEXT
         *
         * its value is saved in selectedMetaDataFieldType
         * @type {Array}
         */
        displayedMetadataObjList: {
            value: []
        },
        /**
         * If f the template that was used to create the widget
         *
         * */
        widgetTemplateId: {
            value: 0
        }
    };

    Y.extend(BaseWidgetList, Y.AbstractWizard, {

        /**
         * Method used to initialize the wizard. It builds the wizard elements and adds the events
         *
         * @method initWizard
         */
        initWizard: function () {
            var instance = this,
                    host = this.get('host'),
                    steps = [],
                    isEdit = instance.get('widgetId') > 0;

            steps.push(instance.getPropertiesStep());
            steps.push(instance.getSearchOptionsStep());
            steps.push(instance.getMetadataStep());
            steps.push(instance.getLayoutStep());
            steps.push(instance.getLayoutStyleStep());

            //Layout Default set

            //add button for templates
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }


            instance.after(FIELD_LAYOUT + "Change", function (e) {
                var instance = e.currentTarget;

                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            new Y.HtmlElement({
                children: [
                    new Y.HtmlElement({
                        cssClass: 'panel-group',
                        children: steps
                    }),

                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        children: [
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right',
                                htmlContent: instance.t('baseWidgetList.save'),
                                onClick: function (e) {
                                    instance.doSaveWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right get-button',
                                htmlContent: instance.t('baseWidgetList.getCode'),
                                onClick: function (e) {
                                    instance.doGetWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right',
                                htmlContent: instance.t('baseWidgetList.cancel'),
                                onClick: function (e) {
                                    instance.doReturnToMyWidgets();
                                }
                            })
                        ]
                    })
                ]
            }).render(host);

            instance._addDropDownEvents();
            instance._layoutSet(true);
        },

        /**
         * Populates object lists wit objects saved in the database
         * @param configuration - the object saved in the database
         */
        initSavedObjects: function (configuration) {
            var instance = this;
            /*if (configuration.publicationType) {
                instance.getAttrs().publicationType= configuration.publicationType;
            }*/
            /**
             * Populate Selected metadata list
             */
            if (configuration.selectedMetaDataFieldType != undefined &&
                    configuration.selectedMetaDataFieldType.length > 0) {

                /**
                 * Populate object Lists with the saved objects form Database.
                 * This can create error if the Widget doesn't has that configuration
                 */

                try {
                    instance.updateMetadataAppearanceList();
                } catch (e) {
                    console.log('error', e);
                }

                try {

                    if (configuration.widgetAppearance != undefined) {
                        instance.generateBasicAppearanceObject(configuration.widgetAppearance);
                    }

                } catch (e) {
                    console.log('error', e);
                }


                /**
                 * This will render the configuration for the MetaData option list.
                 * In case of a widget without this configuration, this will generate and error.
                 */
                try {
                    var metadataBoxOptions = Y.all("#" + instance.get(ELEM_ATTR.NAMESPACE) + "metaselect" + " .metadata-enabled" + " option");
                    var destinationElement = Y.one("#" + instance.get(ELEM_ATTR.NAMESPACE) + 'metaDataTypeSelection');

                    if (metadataBoxOptions && destinationElement) {
                        instance.renderMetaBojects(destinationElement, metadataBoxOptions);
                    }

                } catch (e) {
                    console.log('error', e);
                }

            }
        },


        generateBasicAppearanceObject: function (configuration) {
            var instance = this;
            instance.doBasicAppearanceObjectList(configuration)
        },


        updateMetadataAppearanceList: function () {
            var instance = this,
                    host = this.get('host'),
                    enabledMetadata = [];

            var metadataAppearanceOptions = host.all("#" + "previewMetadata" + " option");
         //   var enabledMetadataOptions = host.all("#" + instance.get(ELEM_ATTR.NAMESPACE) + "metaselect" + " .metadata-enabled" + " option");
            var enabledMetadataOptions = instance.get(METADATA_SAVED_OBJS);

            for (var i = 0; i < enabledMetadataOptions.length; i++) {
                enabledMetadata.push(enabledMetadataOptions[i].key);
            };

            metadataAppearanceOptions.each(function (item, index) {
                if (index == 0) {
                    return; // skip 'Select' option
                }

                var currentValue = item.get(ELEM_ATTR.VALUE).toLowerCase();
                var currentMetadataEnabled = false;
                for (var i = 0; i < enabledMetadata.length; i++) {
                    if (enabledMetadata[i].toLowerCase() == currentValue) {
                        currentMetadataEnabled = true;
                        break;
                    }
                }
                if (currentMetadataEnabled) {
                    item.removeClass('hidden');
                }
                else {
                    item.addClass('hidden');
                }
            });
        },

        updateMetadataAppearanceListNew: function () {
            var instance = this,
                    host = this.get('host');

            var metadataAppearanceOptions = host.all("#" + "previewMetadata" + " option");

            metadataAppearanceOptions.each(function (item, index) {
                if (index == 0) {
                    return; // skip 'Select' option
                }

                var currentValue = item.get(ELEM_ATTR.VALUE).toLowerCase();
                var currentMetadataEnabled = false;
                var metadataObjList = instance.get(METADATA_SAVED_OBJS);
                for (var i = 0; i < metadataObjList.length; i++) {
                    if (metadataObjList[i].key.toLowerCase() == currentValue) {
                        currentMetadataEnabled = true;
                        break;
                    }
                }
                if (currentMetadataEnabled) {
                    item.removeClass('hidden');
                }
                else {
                    item.addClass('hidden');
                }
            });
            instance._resetLayoutEvents();
            instance._layoutSet();
            instance._setLayoutMetadata();
        },

        updateMetadataAppearanceListControlButton: function (controlButtonType, enabled, align) {
            var instance = this;
            var savedMetadata = instance.get(METADATA_SAVED_OBJS);

            var foundAtIndex = -1;
            for (var i = 0; i < savedMetadata.length; i++) {
                if (savedMetadata[i].key == controlButtonType) {
                    foundAtIndex = i;
                    break;
                }
            }
            if (enabled) {
                if (foundAtIndex == -1) {
                    var newMetadataObject = {
                        key: controlButtonType,
                        metadataFieldType: 'button',
                        align: align
                    };
                    savedMetadata.push(newMetadataObject)
                } else {
                    savedMetadata[i].align = align;
                }
            }
            else {
                if (foundAtIndex > -1) {
                    savedMetadata.splice(foundAtIndex, 1);
                }
            }
            instance.set(METADATA_SAVED_OBJS, savedMetadata);

            instance._layoutSet(true);
            instance._setLayoutMetadata();
        },

        setDefaultLayout: function (layoutType) {
            var instance = this,
                    host = instance.get('host'),
                    layoutValues = LAYOUTS,
                    index = Y.Array.indexOf(layoutValues, layoutType) != -1 ? Y.Array.indexOf(layoutValues, layoutType) : 0;

            instance.set(FIELD_LAYOUT, layoutValues[index]);
            instance._layoutSet(true);

        },

        /**
         * sets the layout on layout change
         *
         * @method _layoutSet
         * @param
         * @private
         */
        _layoutSet: function (keepLayoutOrder) {
            var instance = this,
                    host = instance.get('host'),
                    layouts = host.all('.layoutExample'),
                    layoutValues = LAYOUTS,
                    val = instance.get(FIELD_LAYOUT),
                    index = val ? Y.Array.indexOf(layoutValues, val) : 0,
                    layout = val ? layouts.item(index) : null;
            if (val && layout) {
                // remove events
                host.one('.layoutSet').empty();
                host.one('.layoutSet').setHTML(layout.getContent());
                instance._resetLayoutEvents(keepLayoutOrder);
            }
        },

        /**
         * Adds the drop down events after the DOM was build
         *
         * @method _addDropDownEvents
         * @private
         */
        _addDropDownEvents: function () {
            var instance = this;
            //Listen for all drop:over events
            Y.DD.DDM.on('drop:over', function (e) {
                //Get a reference to our drag and drop nodes
                var drag = e.drag.get('node'),
                        drop = e.drop.get('node');

                //Are we dropping on a li node?
                if (drop.hasClass('layout-child')) {
                    //Are we not going up?
                    if (!goingUp) {
                        drop = drop.get('nextSibling');
                    }
                    //Add the node to this list
                    e.drop.get('node').get('parentNode').insertBefore(drag, drop);
                    //Resize this nodes shim, so we can drop on it later.
                    e.drop.sizeShim();
                }
            });

            //Listen for all drag:drag events
            Y.DD.DDM.on('drag:drag', function (e) {
                //Get the last y point
                var y = e.target.lastXY[1];
                //is it greater than the lastY var?
                if (y < lastY) {
                    //We are going up
                    goingUp = true;
                }
                else {
                    //We are going down.
                    goingUp = false;
                }
                //Cache for next check
                lastY = y;
            });

            //Listen for all drag:start events
            Y.DD.DDM.on('drag:start', function (e) {
                //Get our drag object
                var drag = e.target;
                //Set some styles here
                drag.get('node').setStyle('opacity', '.25');
                drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
                drag.get('dragNode').setStyles({
                    opacity: '.5',
                    borderColor: drag.get('node').getStyle('borderColor'),
                    backgroundColor: drag.get('node').getStyle('backgroundColor')
                });
            });
            //Listen for a drag:end events
            Y.DD.DDM.on('drag:end', function (e) {
                var drag = e.target;
                //Put our styles back
                drag.get('node').setStyles({
                    visibility: '',
                    opacity: '1'
                });
                instance._setLayoutMetadata(true);
            });
            //Listen for all drag:drophit events
            Y.DD.DDM.on('drag:drophit', function (e) {
                var drop = e.drop.get('node'),
                        drag = e.drag.get('node');

                //if we are not on a child, we must have been dropped on a parent
                if (drop.hasClass('layout-col')) {
                    if (!drop.contains(drag)) {
                        drop.appendChild(drag);
                    }
                }
            });
        },

        /**
         * This method is used to set the {{#crossLink 'BaseWidgetList/layoutMetadata:attribute'}}{{/crossLink}} attribute
         * after an event that modified the layout metadata structured occurred:
         * - The metadata were rearranged in layout
         * - The {{#crossLink 'BaseWidgetList/layout:attribute'}}{{/crossLink}} was changed
         * - The {{#crossLink 'BaseWidgetList/selectedMetadata:attribute'}}{{/crossLink}} was changed
         *
         * @method _setLayoutMetadata
         * @private
         */
        _setLayoutMetadata: function (reorder) {
            var instance = this,
                    host = instance.get('host'),
                    layoutSet = host.one('.layoutSet'),
                    layoutMetadata = [];

            if (layoutSet != null) {
                var cols = layoutSet.all('.layout-col');
                cols.each(function (item, index) {
                    var metadata = [],
                            items = item.all('.layout-child');
                    items.each(function (child) {
                        var val = child.getAttribute('data-value');
                        if (val) {
                            metadata.push(val);
                        }
                    });
                    layoutMetadata.push(metadata);
                });
            }

            if (reorder === undefined || reorder === false) {
                const currentOrder = instance.get(FIELD_LAYOUT_METADATA);
                if (layoutMetadata && layoutMetadata.length === 2 && currentOrder && currentOrder.length === 2) {
                    try {
                        layoutMetadata[0].sort((a, b) => currentOrder[0].indexOf(a) - currentOrder[0].indexOf(b));
                        layoutMetadata[1].sort((a, b) => currentOrder[1].indexOf(a) - currentOrder[1].indexOf(b));
                    } catch (e) {
                        console.log('error sorting layout metadata.', e);
                    }
                } else if (layoutMetadata && layoutMetadata.length === 1 && currentOrder && currentOrder.length === 1) {
                    try {
                        layoutMetadata[0].sort((a, b) => currentOrder[0].indexOf(a) - currentOrder[0].indexOf(b));
                    } catch (e) {
                        console.log('error sorting layout metadata.', e);
                    }
                }
            }

            instance.set(FIELD_LAYOUT_METADATA, layoutMetadata);
        },

        /**
         * This method is used to rebuild the selected metadata display in the layout and to
         * add the drag and drop events, when:
         * - The {{#crossLink 'BaseWidgetList/layout:attribute'}}{{/crossLink}} was changed
         * - The {{#crossLink 'BaseWidgetList/selectedMetadata:attribute'}}{{/crossLink}} was changed
         *
         * @method _resetLayoutEvents
         * @private
         */
        _resetLayoutEvents: function (keepLayoutOrder) {
            var instance = this,
                    host = instance.get('host'),
                    selectedMetadata = instance.get(METADATA_SAVED_OBJS),
                    layoutMetadata = instance.get(FIELD_LAYOUT_METADATA),
                    layoutSet = host.one('.layoutSet'),
                    firstCol = layoutSet.one('.layout-col'),
                    id = layoutSet.get('id'), i, j, size, maxSize;

            if (!keepLayoutOrder && selectedMetadata.length == 0 || !firstCol) {
                // skip if no metadata selected or no layout selected
                return;
            }

            instance.backwardCompatibilityShareOrderButtons();

            // empty the cols and reset styles
            var layoutColumns = layoutSet.all('.layout-col');
            layoutColumns.empty();


            if (keepLayoutOrder && layoutMetadata) {
                var addedMetadata = [];
                layoutColumns.each(function (columnNode, columnIndex) {
                    if (columnIndex < layoutMetadata.length) {
                        for (var i = 0; i < layoutMetadata[columnIndex].length; i++) {
                            var layoutMetadataKey = layoutMetadata[columnIndex][i];
                            var metadata = selectedMetadata.find(function (metadata) {
                                return metadata.key == layoutMetadataKey;
                            });
                            columnNode.append(instance.getLayoutMetadataHtml(metadata));
                            addedMetadata.push(metadata);
                        }
                    }
                });
                if (addedMetadata.length < selectedMetadata.length) {
                    for (var i = 0; i < selectedMetadata.length; i++) {
                        var metadataWasAdded = false;
                        for (var j = 0; j < addedMetadata.length; j++) {
                            if (addedMetadata[j].key == selectedMetadata[i].key) {
                                metadataWasAdded = true;
                                break;
                            }
                        }
                        if (!metadataWasAdded) {
                            layoutColumns.item(0).append(instance.getLayoutMetadataHtml(selectedMetadata[i]));
                        }
                    }
                }
            }
            else {
                var layoutElementsColumnMapping = {};
                layoutMetadata.forEach(function (layoutElements, layoutIndex) {
                    layoutElements.forEach(function (layoutElement) {
                        layoutElementsColumnMapping[layoutElement] = layoutIndex;
                    });
                });
                for (var i = 0; i < selectedMetadata.length; i++) {
                    var targetColumnIndex = 0;
                    if (layoutColumns.size() > 1 && selectedMetadata[i] && layoutElementsColumnMapping[selectedMetadata[i].key]) {
                        targetColumnIndex = layoutElementsColumnMapping[selectedMetadata[i].key];
                    }
                    var metadata = selectedMetadata[i];

                    layoutColumns.item(targetColumnIndex).append(instance.getLayoutMetadataHtml(metadata));
                }
            }


            //Get the list of li's in the lists and make them draggable
            var lis = host.one('.layoutSet').all('.layout-child');
            lis.each(function (v, k) {
                var dd = new Y.DD.Drag({
                    node: v,
                    target: {
                        padding: '0 0 0 20'
                    }
                }).plug(Y.Plugin.DDProxy, {
                    moveOnEnd: false
                }).plug(Y.Plugin.DDConstrained, {
                    constrain2node: '#' + id
                });
            });

            //Create simple targets for the 2 lists.
            var uls = host.one('.layoutSet').all('.layout-col');
            uls.each(function (v, k) {
                var tar = new Y.DD.Drop({
                    node: v
                });
            });

            lis.all('.icon-metadata-move').on('click', function (e) {
                var node = e.currentTarget;
                var metadataKey = node.ancestor('.layout-child').getData('value');
                var newAlign = '';
                if (node.hasClass('icon-chevron-left')) {
                    newAlign = 'left';
                } else if (node.hasClass('icon-chevron-right')) {
                    newAlign = 'right';
                }
                instance.updateMetadataAppearanceListControlButton(metadataKey, true, newAlign);
            });
        },

        getLayoutMetadataHtml: function(metadata) {
            if (!metadata) {
                return '';
            }
            var instance = this;

            var layoutMetadataKey = metadata.key;
            var includeAlignControl = layoutMetadataKey == 'shareButton' || layoutMetadataKey == 'orderButton';
            var layoutClass = 'row layout-child ' + 'layout-' + layoutMetadataKey;

            var htmlBuilder = '';
            htmlBuilder += '<div class="' + layoutClass + '" data-value="' + layoutMetadataKey + '">';
            htmlBuilder += '<div class="col-md-1">';
            htmlBuilder += '<span class="icon-move"></span>';
            htmlBuilder += '</div>';
            htmlBuilder += '<div class="col-md-11 ' + (includeAlignControl && metadata.align == 'right' ? ' align-right' : '') + '">';
            htmlBuilder += (includeAlignControl && metadata ? '<span class="icon-metadata-move icon-chevron-left ' + (metadata.align == 'right' ? '' : 'hidden') +'"></span>' : '');
            htmlBuilder += '<span class="layout-metadata-label">' + instance.t('baseWidgetList.' + layoutMetadataKey) + '</span>';
            htmlBuilder += (includeAlignControl && metadata ? '<span class="icon-metadata-move icon-chevron-right ' + (!metadata.align || metadata.align == 'left' ? '' : 'hidden') +'"></span>' : '');
            htmlBuilder += '</div>';
            htmlBuilder += '</div>';
            return htmlBuilder;
        },

        backwardCompatibilityShareOrderButtons: function() {
            var instance = this,
                selectedMetadata = instance.get(METADATA_SAVED_OBJS),
                shareThisEnabled = instance.get('showSharePublicationButton'),
                orderPublicationEnabled = instance.get('showOrderPublicationButton');

            var selectedMetadataModified = false;

            var shareButtonFound = false;
            var orderButtonFound = false;
            for (var i = 0; i < selectedMetadata.length; i++) {
                if (selectedMetadata[i].key == 'shareButton') {
                    shareButtonFound = true;
                }
                if (selectedMetadata[i].key == 'orderButton') {
                    orderButtonFound = true;
                }
                if (shareButtonFound && orderButtonFound) {
                    break;
                }
            }

            if (shareThisEnabled && !shareButtonFound) {
                selectedMetadata.push({
                    key: 'shareButton',
                    metadataFieldType: 'button',
                    align: 'left'
                });
                selectedMetadataModified = true;
            }

            if (orderPublicationEnabled && !orderButtonFound) {
                selectedMetadata.push({
                    key: 'orderButton',
                    metadataFieldType: 'button',
                    align: 'left'
                });
                selectedMetadataModified = true;
            }

            if (selectedMetadataModified) {
                instance.set(METADATA_SAVED_OBJS, selectedMetadata);
            }
        },

        initLayoutItem: function () {
            var instance = this;
            var layoutList = [];

            var existingLayout = instance.get('layout');
            var existingLayoutMetadata = instance.get('layoutMetadata');

            if (existingLayout && existingLayoutMetadata) {
                instance.setDefaultLayout(existingLayout);
                instance._resetLayoutEvents(true);
            }
            else {
                layoutList = Y.all('.layout-set-select input[type="radio"]');
                if (layoutList != undefined && layoutList != null && layoutList.size() > 0) {
                    if (layoutList.first()) {
                        instance.setDefaultLayout('l1');
                    }
                }
            }
        },

        /**
         * @method getPropertiesStep
         * @return {PanelElement} the panel with widget properties configuration
         */
        getPropertiesStep: function () {
            throw "getPropertiesStep is unimplemented!";
        },

        /**
         * @method getSearchOptionsStep
         * @return {PanelElement} a panel with widget metadata selection
         */
        getSearchOptionsStep: function () {
            var instance = this,
                    step, panelChildren = [];

            panelChildren.push(instance.getLanguageNodes());

            step = new Y.PanelElement({
                label: instance.t('baseWidgetList.searchOptions'),
                children: panelChildren
            });

            return step;
        },

        /**
         * @method getMetadataStep
         * @return {PanelElement} a panel with widget metadata selection
         */
        getMetadataStep: function () {
            var instance = this,
                    step, options = [], i;

            for (i = 0; i < METADATA.length; i++) {
                options.push({
                    key: METADATA[i].key,
                    value: instance.t('baseWidgetList.' + METADATA[i].key)
                })
            }
            step = new new Y.HtmlElement({
                id: instance.get(ELEM_ATTR.NAMESPACE) + "metaselect",
                wrapperCssClass: 'row',
                children: [
                    new Y.MetadataEditInTableElement({
                        label: instance.t('baseWidgetList.displayedMetadata'),
                        modelInstance: instance,
                        name: FIELD_SELECTED_METADATA,
                        options: options
                    }),
                    instance.getShareThisSelector(),
                    instance.getOrderThisSelector(),
                ]
            });

            return step;
        },

        getFontFamilyList: function () {
            return fontList;
        },

        getBorderWidthList: function () {
            return borderList;
        },

        getHElementList: function () {
            return hElemList;
        },

        /**
         * Displays all the appearance tabs, Basic and Metadata selection
         * @param basicConfiguration is null fi there is no configuration
         * @param advancedConfiguration is null fi there is no configuration
         * @param displayBasic - true to create object, false not to create object
         * @param displayAdvanced - true to create object, false not to create object
         * @returns {Y.TabView}
         */
        getDisplayAppearence: function (basicConfiguration, advancedConfiguration, displayBasic, displayAdvanced) {
            var instance = this;

            var widgetAppearanceList = [];

            widgetAppearance = {};
            metadataAppearanceList = [];

            /**
             * If false, the configuration is not created and will not be visible
             */
            if (displayBasic != false) {
                //Basic appearance configuration
                widgetAppearance = instance.doBasicAppearanceObjectList(basicConfiguration);
                widgetAppearanceList.push(
                        new Y.HtmlElement({
                            id: 'basicAppearanceLeft',
                            cssClass: 'col-md-6 appearance appearance-basic row',
                            children: widgetAppearance,
                            name: APPEARANCE_BASIC_DISPLAY
                        })
                )
            }
            /**
             * If false, the configuration is not created and will not be visible
             */
            if (displayAdvanced != false) {
                // MetaData appearance configuration
                metadataAppearanceList = instance.doAdvancedAppearanceObjectList(advancedConfiguration);

                widgetAppearanceList.push(
                        new Y.HtmlElement({
                            id: 'basicAppearanceRight',
                            cssClass: 'col-md-6 appearance appearance-advanced',
                            children: metadataAppearanceList,
                            name: APPEARANCE_BASIC_DISPLAY_OBJ_LIST
                        })
                );
            }

            var basicContentTab = new Y.HtmlElement({
                id: 'basicAppearance',
                children: widgetAppearanceList
            });

            var advancedContentTab = new Y.HtmlElement({
                children: [
                    new Y.TextAreaElement({
                        label: instance.t('searchResult.appearance.css'),
                        modelInstance: instance,
                        id: FIELD_ADVANCED_SET_APPEARANCE,
                        name: FIELD_ADVANCED_SET_APPEARANCE,
                        cssClass: 'sr-exclude-text-area',
                        onFocus: function (e) {
                            // save the text area value in instance
                            e.target.lastValue = e.target.get('value');
                        },
                        onBlur: function (e) {
                            // verify if the value was changed
                            if (e.target.get('value') !== e.target.lastValue) {
                                instance.advancedToBasicAppearanceCSS();
                            }
                        }
                    })
                ]
            });

            var tabView = new Y.TabView({
                id: 'appearanceTabView',
                children: [
                    {
                        content: basicContentTab.render().getDOMNode(),
                        label: instance.t('baseWidgetList.appearance.basic')
                    },
                    {
                        content: advancedContentTab.render().getDOMNode(),
                        label: instance.t('baseWidgetList.appearance.advanced')
                    }
                ]
            });

            var tabClickEvent = tabView.on('click', function (e) {
                var selectedTabIndex = this.indexOf(this.get('selection'));
                if (selectedTabIndex == 0) {
                    // do nothing
                }
                if (selectedTabIndex == 1) {
                    instance.initAdvancedAppearanceCSS();
                }

                // workaround: detach event from tabView and attach to tab-label
                tabClickEvent.detach();
                Y.all('#appearanceTabView .tab-label').each(function (tab) {
                    if (tab.html() == instance.t('baseWidgetList.appearance.basic')) {
                        // do nothing
                    }
                    else if (tab.html() == instance.t('baseWidgetList.appearance.advanced')) {
                        tab.on('click', function () {
                            instance.initAdvancedAppearanceCSS();
                        });
                    }
                });

            });
            return tabView;
        },

        /**
         * Basic appearance configuration. This method returns the elements for the basic appearance
         * @param configuration is null fi there is no configuration
         * @returns {Array} - YUI structured elements list
         */
        doBasicAppearanceObjectList: function (configuration) {
            var instance = this;
            var widgetAppearance = [];
            var basicConfiguration = BASIC_APPEARANCE_DFAULTS;
            var fontFamilyIndex = 1;
            var borderIndex = 1;

            /**
             * If the configuration exists then the populated object is returned
             */
            if (configuration != null && configuration != undefined && (configuration instanceof Object)) {

                basicConfiguration = {
                    fontSize: '12 px',
                    marginWidth: '2 px',
                    paddingWidth: '2 px',
                    fontColor: '#2873eb',
                    fontFamily: configuration.fontFamily,
                    borderWidth: configuration.borderWidth,
                    backgroundColor: configuration.backgroundColor,
                    borderColor: configuration.borderColor,
                    minHeight: configuration.minHeight ? (configuration.minHeight == 0 ? '0' : configuration.minHeight) : '0',
                    minWidth: configuration.minWidth ? (configuration.minWidth == 0 ? '0' : configuration.minWidth) : '0',
                    height: configuration.height ? (configuration.height == 0 ? '0' : configuration.height) : '0',
                    width: configuration.width ? (configuration.width == 0 ? '0' : configuration.width) : '0'
                }


                for (var j = 0; j < instance.getFontFamilyList().length; j++) {
                    if (configuration.fontFamily == instance.getFontFamilyList()[j]) {
                        fontFamilyIndex = j;
                    }
                }


                for (var j = 0; j < instance.getBorderWidthList().length; j++) {
                    if (configuration.borderWidth == instance.getBorderWidthList()[j]) {
                        borderIndex = j;
                    }
                }
            }

            widgetAppearance.push(new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'form-group col-md-12 layout-group-container',
                children: [
                    new Y.SliderInputElement({
                        label: instance.t('searchResult.appearance.height'),
                        name: APPEARANCE_BASIC_PREVIEW_HEIGHT,
                        id: APPEARANCE_BASIC_PREVIEW_HEIGHT,
                        value: basicConfiguration.height,
                        sliderMin: 0,
                        sliderMax: 1080,
                        sliderWidth: '90',
                        modelInstance: instance,
                        wrapperCssClass: 'form-group setterComponent layout-group-container',
                        cssClass: 'col-md-7',
                        onChange: function (e) {
                            instance.updateBasicAppearance(APPEARANCE_BASIC_PREVIEW_HEIGHT, e.currentTarget.get('value'));
                        }
                    })
                ]
            }));

            widgetAppearance.push(new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'form-group col-md-12 layout-group-container',
                children: [
                    new Y.SliderInputElement({
                        label: instance.t('searchResult.appearance.width'),
                        name: APPEARANCE_BASIC_PREVIEW_WIDTH,
                        id: APPEARANCE_BASIC_PREVIEW_WIDTH,
                        value: basicConfiguration.width,
                        sliderMin: 0,
                        sliderMax: 1080,
                        sliderWidth: '90',
                        modelInstance: instance,
                        wrapperCssClass: 'form-group setterComponent layout-group-container',
                        cssClass: 'col-md-7',
                        onChange: function (e) {
                            instance.updateBasicAppearance(APPEARANCE_BASIC_PREVIEW_WIDTH, e.currentTarget.get('value'));
                        }
                    })
                ]
            }));

            widgetAppearance.push(new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'form-group col-md-12 layout-group-container',
                children: [
                    new Y.SliderInputElement({
                        label: instance.t('searchResult.appearance.min.height'),
                        name: APPEARANCE_BASIC_PREVIEW_MIN_HEIGHT,
                        id: APPEARANCE_BASIC_PREVIEW_MIN_HEIGHT,
                        value: basicConfiguration.minHeight,
                        sliderMin: 0,
                        sliderMax: 1080,
                        sliderWidth: '90',
                        modelInstance: instance,
                        wrapperCssClass: 'form-group setterComponent layout-group-container',
                        cssClass: 'col-md-7',
                        onChange: function (e) {
                            instance.updateBasicAppearance(APPEARANCE_BASIC_PREVIEW_MIN_HEIGHT, e.currentTarget.get('value'));
                        }
                    })
                ]
            }));

            widgetAppearance.push(new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'form-group col-md-12 layout-group-container',
                children: [
                    new Y.SliderInputElement({
                        label: instance.t('searchResult.appearance.min.width'),
                        name: APPEARANCE_BASIC_PREVIEW_MIN_WIDTH,
                        id: APPEARANCE_BASIC_PREVIEW_MIN_WIDTH,
                        value: basicConfiguration.minWidth,
                        sliderMin: 0,
                        sliderMax: 1080,
                        sliderWidth: '90',
                        modelInstance: instance,
                        wrapperCssClass: 'form-group setterComponent layout-group-container',
                        cssClass: 'col-md-7',
                        onChange: function (e) {
                            instance.updateBasicAppearance(APPEARANCE_BASIC_PREVIEW_MIN_WIDTH, e.currentTarget.get('value'));
                        }
                    })
                ]
            }));

            widgetAppearance.push(
                    instance.getSettingSelector(
                            APPEARANCE_BASIC_PREVIEW_FONT_FAMILY,
                            instance.t('searchResult.appearance.font.family'),
                            instance.getFontFamilyList()[fontFamilyIndex],
                            instance.getFontFamilyList(),
                            APPEARANCE_BASIC_PREVIEW_FONT_FAMILY,
                            widgetAppearance));

            widgetAppearance.push(new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'form-group col-md-12 layout-group-container',
                children: [
                    new Y.ColorPickerInputElement({
                        label: instance.t('searchResult.appearance.background.color'),
                        name: APPEARANCE_BASIC_PREVIEW_BACKGROUND_COLOR,
                        id: APPEARANCE_BASIC_PREVIEW_BACKGROUND_COLOR,
                        value: basicConfiguration.backgroundColor,
                        modelInstance: instance,
                        wrapperCssClass: 'form-group setterComponent layout-group-container',
                        cssClass: 'col-md-7',
                        onChange: function (e) {
                            instance.updateBasicAppearance(APPEARANCE_BASIC_PREVIEW_BACKGROUND_COLOR, e.currentTarget.get('value'));
                        }
                    })
                ]
            }));

            widgetAppearance.push(
                    instance.getSettingSelector(
                            APPEARANCE_BASIC_PREVIEW_BORDER_WIDTH,
                            instance.t('searchResult.appearance.border.width'),
                            instance.getBorderWidthList()[borderIndex],
                            instance.getBorderWidthList(),
                            APPEARANCE_BASIC_PREVIEW_BORDER_WIDTH,
                            widgetAppearance));

            widgetAppearance.push(new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'form-group col-md-12 layout-group-container',
                children: [
                    new Y.ColorPickerInputElement({
                        label: instance.t('searchResult.appearance.border.color'),
                        name: APPEARANCE_BASIC_PREVIEW_BORDER_COLOR,
                        id: APPEARANCE_BASIC_PREVIEW_BORDER_COLOR,
                        value: basicConfiguration.borderColor,
                        modelInstance: instance,
                        wrapperCssClass: 'form-group setterComponent layout-group-container',
                        cssClass: 'col-md-7',
                        onChange: function (e) {
                            instance.updateBasicAppearance(APPEARANCE_BASIC_PREVIEW_BORDER_COLOR, e.currentTarget.get('value'));
                        }
                    })
                ]
            }));

            return widgetAppearance;
        },

        /**
         * Advanced appearance configuration. This method returns the elements for the advanced appearance
         * @param configuration is null fi there is no configuration
         * @returns {Array} - YUI structured elements list
         */
        doAdvancedAppearanceObjectList: function (configuration) {
            var instance = this;
            var METADATA = instance.getMetadata();
            var metadataAppearanceList = [];
            var METADATA_SEL = METADATA_SELECT.concat(METADATA);


            var advancedConfiguration = BASIC_APPEARANCE_DFAULTS;


            if (configuration != null && configuration.length > 0) {
                var configurationLength=configuration.length;
                for (var i = 0; i < configurationLength; i++) {


                    metaDataAppearanceObjs.push(
                            {
                                fontColor: configuration[i].fontColor,
                                fontSize: configuration[i].fontSize,
                                htmlElement: configuration[i].htmlElement,
                                id: configuration[i].metadataKey,
                                margin: configuration[i].margin,
                                metadata: configuration[i].metadataKey,
                                padding: configuration[i].padding,
                                maxWidth: configuration[i].maxWidth ? configuration[i].maxWidth : ''
                            }
                    )
                }
            }

            //Creates the list of objects
            metadataAppearanceList.push(
                    instance.getSettingSelector(
                            APPEARANCE_BASIC_PREVIEW_METADATA,
                            instance.t('searchResult.appearance.metadata'),
                            METADATA_SEL[0],
                            METADATA_SEL,
                            APPEARANCE_BASIC_PREVIEW_METADATA,
                            metadataAppearanceList,
                            ADVANCED_APPEARANCE_METADATA));

            metadataAppearanceList.push(
                    instance.getSettingSelector(
                            APPEARANCE_BASIC_PREVIEW_TITLE_H,
                            instance.t('searchResult.appearance.html.element'),
                            instance.getHElementList()[0],
                            instance.getHElementList(),
                            APPEARANCE_BASIC_PREVIEW_TITLE_H,
                            metadataAppearanceList,
                            ADVANCED_APPEARANCE_PROPERTY + ' hidden'));

            metadataAppearanceList.push(
                    instance.getInputObject(
                            APPEARANCE_BASIC_PREVIEW_FONT_SIZE,
                            instance.t('searchResult.appearance.font.size'),
                            advancedConfiguration.fontSize,
                            ADVANCED_APPEARANCE_PROPERTY + ' hidden'));

            metadataAppearanceList.push(new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'form-group col-md-12 layout-group-container ' + ADVANCED_APPEARANCE_PROPERTY + ' hidden',
                children: [
                    new Y.ColorPickerInputElement({
                        label: instance.t('searchResult.appearance.font.color'),
                        name: APPEARANCE_BASIC_PREVIEW_FONT_COLOR,
                        id: APPEARANCE_BASIC_PREVIEW_FONT_COLOR,
                        value: advancedConfiguration.fontColor,
                        modelInstance: instance,
                        wrapperCssClass: 'form-group setterComponent layout-group-container',
                        cssClass: 'col-md-7',
                        onChange: function (e) {
                            instance.updateOptionsInstances(e.target, e.target.get("value"));
                        }
                    })
                ]
            }));

            metadataAppearanceList.push(
                    instance.getInputObject(
                            APPEARANCE_BASIC_PREVIEW_MARGIN_WIDTH,
                            instance.t('searchResult.appearance.margin.width'),
                            advancedConfiguration.marginWidth,
                            ADVANCED_APPEARANCE_PROPERTY + ' hidden'));

            metadataAppearanceList.push(
                    instance.getInputObject(
                            APPEARANCE_BASIC_PREVIEW_PADDING_WIDTH,
                            instance.t('searchResult.appearance.padding.width'),
                            advancedConfiguration.paddingWidth,
                            ADVANCED_APPEARANCE_PROPERTY + ' hidden'));

            metadataAppearanceList.push(
                    instance.getInputObject(
                            APPEARANCE_BASIC_PREVIEW_MAX_WIDTH,
                            instance.t('searchResult.appearance.maxWidth'),
                            advancedConfiguration.maxWidth,
                            ADVANCED_APPEARANCE_PROPERTY + ' ' + APPEARANCE_BASIC_PREVIEW_MAX_WIDTH + ' hidden'));

            return metadataAppearanceList;
        },

        /**
         * Returns the DOM object list for the header checkBoxes
         * @returns {Array} - List of objects.
         */
        getHeaderFooterOptionList: function (field) {
            var instance = this;
            var headerOptions = [];
            var options = instance.getOptions();

            // widget types
            // SEARCH(1L), SEARCH_RESULT(2L), SELECTED_PUBLICATIONS(3L), SEMANTIC_SEARCH(4L), PUBLICATION_DETAIL(5L), ORGANIZATION(6L),
            // PUBLIC_PROCUREMENT_SEARCH(7L), PUBLIC_PROCUREMENT_SEARCH_RESULT(8L), PUBLIC_PROCUREMENT_SELECTED(9L), PUBLIC_PROCUREMENT_DETAILS(10L);

            for (let i = 0; i < options.length; i++) {
                if (options[i].key === "rss" || options[i].key === "alert" || options[i].key === "filters" || options[i].key === "sortBy") {
                    options[i].disabled = true;
                }
                if ((options[i].key === "rss" || options[i].key === "alert" || options[i].key === "filters") &&
                    (instance.get("widgetType") === 2 || instance.get("widgetType") === 8)) {
                    options[i].disabled = false;
                }
                if (options[i].key === "sortBy" &&
                    (instance.get("widgetType") === 2 || instance.get("widgetType") === 3 ||
                    instance.get("widgetType") === 8 || instance.get("widgetType") === 9)) {
                    options[i].disabled = false;
                }

            }

            for (let i = 0; i < options.length; i++) {
                if (options[i].key === 'sortBy') {
                    let sortByOptions;
                    if (instance.get("widgetType") === 8) {
                        sortByOptions = [
                            {
                                key: 'relevance',
                                label: instance.t('baseWidgetList.orderBy.relevance')
                            },
                            {
                                key: 'title',
                                label: instance.t('baseWidgetList.orderBy.title')
                            },
                            {
                                key: 'buyer',
                                label: instance.t('baseWidgetList.orderBy.buyer')
                            },
                            {
                                key: 'date',
                                label: instance.t('baseWidgetList.orderBy.procurementDate')
                            }
                        ];
                    } else if (instance.get("widgetType") === 9) {
                        sortByOptions = [
                            {
                                key: 'title',
                                label: instance.t('baseWidgetList.orderBy.title')
                            },
                            {
                                key: 'buyer',
                                label: instance.t('baseWidgetList.orderBy.buyer')
                            },
                            {
                                key: 'date',
                                label: instance.t('baseWidgetList.orderBy.procurementDate')
                            }
                        ];
                    } else {
                        sortByOptions = [
                            {
                                key: 'author',
                                label: instance.t('baseWidgetList.orderBy.author')
                            },
                            {
                                key: 'collection',
                                label: instance.t('baseWidgetList.orderBy.collection')
                            },
                            {
                                key: 'date',
                                label: instance.t('baseWidgetList.orderBy.publicationDate')
                            },
                            {
                                key: 'relevance',
                                label: instance.t('baseWidgetList.orderBy.relevance')
                            },
                            {
                                key: 'subject',
                                label: instance.t('baseWidgetList.orderBy.subject')
                            },
                            {
                                key: 'title',
                                label: instance.t('baseWidgetList.orderBy.title')
                            }
                        ];
                    }
                    headerOptions.push(new Y.CheckboxWithOptionsElement({
                        label: instance.t('searchResult.' + options[i].key),
                        value: options[i].key,
                        disabled: options[i].disabled,
                        modelInstance: instance,
                        name: field,
                        optionsArrayField: FIELD_ENABLED_SORT_BY_CRITERIA,
                        optionsArray: sortByOptions
                    }));
                }

                else if (options[i].key === 'filters' ) {
                    if(!(field === FIELD_HEADER)){
                        continue;
                    }
                    var filterOptionsArray = [
                        {
                            key: 'collection',
                            label: instance.t('baseWidgetList.filters.collection')
                        },
                        {
                            key: 'subject',
                            label: instance.t('baseWidgetList.filters.subject')
                        },
                        {
                            key: 'author',
                            label: instance.t('baseWidgetList.filters.author')
                        },
                        {
                            key: 'language',
                            label: instance.t('baseWidgetList.filters.language')
                        },
                        {
                            key: 'formats',
                            label: instance.t('baseWidgetList.filters.formats')
                        },
                        {
                            key: 'studies',
                            label: instance.t('baseWidgetList.filters.studies')
                        }
                    ];
                    if (instance.get("widgetType") == 2) {

                        filterOptionsArray.unshift({
                            key: 'text',
                                    label: instance.t('baseWidgetList.filters.text')
                        });
                        filterOptionsArray.push({
                            key: 'topics',
                            label: instance.t('baseWidgetList.filters.topics'),
                            options:Liferay.portal2012[instance.get('namespace') + "topicsList"]
                        });
                    }
                    if (instance.get("widgetType") == 3) {
                        filterOptionsArray.unshift({
                            key: 'dateTo',
                            label: instance.t('baseWidgetList.filters.dateTo')
                        });
                        filterOptionsArray.unshift({
                            key: 'dateFrom',
                            label: instance.t('baseWidgetList.filters.dateFrom')
                        });
                        filterOptionsArray.unshift({
                            key: 'keyword',
                            label: instance.t('baseWidgetList.filters.keyword')
                        });
                        filterOptionsArray.push({
                            key: 'custom',
                            label: instance.t('baseWidgetList.filters.custom'),
                            options:Liferay.portal2012[instance.get('namespace') + "customList"]
                        });
                    }

                    if (instance.get("widgetType") === 8) {
                        filterOptionsArray = [
                            {
                                key: 'text',
                                label: instance.t('baseWidgetList.filters.text')
                            },
                            {
                                key: 'cpv',
                                label: instance.t('baseWidgetList.filters.cpv')
                            },
                            {
                                key: 'nuts',
                                label: instance.t('baseWidgetList.filters.nuts')
                            },
                            {
                                key: 'buyer',
                                label: instance.t('baseWidgetList.filters.buyer')
                            },
                            {
                                key: 'companiesAwarded',
                                label: instance.t('baseWidgetList.filters.companiesAwarded')
                            },
                            {
                                key: 'publicationYear',
                                label: instance.t('baseWidgetList.filters.publicationYear')
                            },
                            {
                                key: 'status',
                                label: instance.t('baseWidgetList.filters.status')
                            }
                        ];
                    }
                    var filterOptionsCheckbox = new Y.CheckboxWithOptionsElement({
                        label: instance.t('searchResult.' + options[i].key),
                        value: options[i].key,
                        disabled: options[i].disabled,
                        modelInstance: instance,
                        name: field,
                        optionsArrayField: FIELD_ENABLED_FILTERS,
                        optionsArray: filterOptionsArray,
                        subOptionsArrayField:FIELD_ENABLED_TOPICS
                    });

                    filterOptionsCheckbox.on('click', function (e) {
                        addTopicsList(instance);
                    });
                    headerOptions.push(filterOptionsCheckbox);
                }
                else {
                    headerOptions.push(new Y.CheckboxElement({
                        label: instance.t('searchResult.' + options[i].key),
                        value: options[i].key,
                        disabled: options[i].disabled,
                        modelInstance: instance,
                        name: field
                    }));
                }
            }

            return headerOptions;
        },

        /**
         * Returns the DOM object list for the format types checkBoxes
         * @returns {Array} - List of objects.
         */
        getFormatOptionList: function () {
            var instance = this;
            var formatsOptions = [], i;
            var options = FORMAT_OPTIONS;

            for (i = 0; i < options.length; i++) {
                formatsOptions.push(new Y.CheckboxElement({
                    label: instance.t('searchResult.format.' + options[i].key),
                    value: options[i].key,
                    disabled: options[i].disabled,
                    modelInstance: instance,
                    name: FIELD_FORMAT_OPTIONS
                }));
            }

            return formatsOptions;
        },


        getMetadataDynamicSelection: function () {
            var instance = this, options = [], i;

            for (i = 0; i < METADATA.length; i++) {
                options.push({
                    key: METADATA[i].key,
                    value: instance.t('baseWidgetList.' + METADATA[i].key)
                })
            }
            return options;
        },

        /**
         * Retruns the metadata object
         *
         * @returns {{value: string, key: string, type: string}[]}
         */
        getMetadata: function () {
            return METADATA;
        },

        /**
         * Get options to be displayed in a widget
         * @returns {{key: string, disabled: boolean}[]}
         */
        getOptions: function () {
            return OPTIONS;
        },
        /**
         * @method getLayoutStep
         * @return {PanelElement} a panel with widget metadata selection
         */
        getLayoutStep: function () {
            var instance = this,
                    step, options = METADATA,
                    initialLayout;

            var layoutFlexibleColOptions = [
                {key: 1, value: "1/12"},
                {key: 2, value: "2/12"},
                {key: 3, value: "3/12"},
                {key: 4, value: "4/12"},
                {key: 5, value: "5/12"},
                {key: 6, value: "6/12"},
                {key: 7, value: "7/12"},
                {key: 8, value: "8/12"},
                {key: 9, value: "9/12"},
                {key: 10, value: "10/12"},
                {key: 11, value: "11/12"}
            ];
            var savedFlexibleRatio = instance.get(FIELD_LAYOUT_FLEXIBLE_RATIO);
            var savedFlexibleRatioCol1, savedFlexibleRatioCol2 = 6;
            if (savedFlexibleRatio && savedFlexibleRatio.indexOf('-') > -1) {
                var split = savedFlexibleRatio.split("-");
                savedFlexibleRatioCol1 = split[0];
                savedFlexibleRatioCol2 = split[1];
            }

            step = new Y.PanelElement({
                label: instance.t('baseWidgetList.itemLayout'),
                children: [
                    new Y.HtmlElement({
                        cssClass: 'container-fluid container-fluid-legacy row-legacy',
                        children: [
                            new Y.HtmlElement({
                                cssClass: 'col-xs-5 col-sm-5',
                                children: [
                                    new Y.HtmlElement({
                                        cssClass: 'container-fluid container-fluid-legacy row-legacy',
                                        children: [
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-5 col-sm-5 layout-set-select',
                                                children: [
                                                    new Y.RadioElement({
                                                        label: '1',
                                                        value: 'l1',
                                                        modelInstance: instance,
                                                        checked: true,
                                                        name: FIELD_LAYOUT

                                                    })
                                                ]
                                            }),
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-7 col-sm-7',
                                                children: [
                                                    new Y.HtmlElement({
                                                        cssClass: 'col-xs-12 col-sm-12 layoutExample',
                                                        htmlContent: '<div class="container-fluid container-fluid-legacy">' +
                                                        '<div class="row-legacy">' +
                                                        '<div class="col-xs-12 col-sm-12 layout-col"></div>' +
                                                        '</div>' +
                                                        '</div>'
                                                    })
                                                ]
                                            })
                                        ]
                                    }),
                                    new Y.HtmlElement({
                                        cssClass: 'container-fluid container-fluid-legacy row-legacy',
                                        children: [
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-5 col-sm-5 layout-set-select',
                                                children: [
                                                    new Y.RadioElement({
                                                        label: '1+1',
                                                        value: 'l11',
                                                        modelInstance: instance,
                                                        name: FIELD_LAYOUT
                                                    })
                                                ]
                                            }),
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-7 col-sm-7',
                                                children: [
                                                    new Y.HtmlElement({
                                                        cssClass: 'col-xs-12 col-sm-12 layoutExample',
                                                        htmlContent: '<div class="container-fluid container-fluid-legacy">' +
                                                        '<div class="row-legacy"><div class="col-xs-6 col-sm-6 layout-col"></div>' +
                                                        '<div class="col-xs-6 col-sm-6 layout-col"></div></div>' +
                                                        '</div>'
                                                    })
                                                ]
                                            })
                                        ]
                                    }),
                                    new Y.HtmlElement({
                                        cssClass: 'container-fluid container-fluid-legacy row-legacy',
                                        children: [
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-5 col-sm-5 layout-set-select',
                                                children: [
                                                    new Y.RadioElement({
                                                        label: '1+2',
                                                        value: 'l12',
                                                        modelInstance: instance,
                                                        name: FIELD_LAYOUT
                                                    })
                                                ]
                                            }),
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-7 col-sm-7',
                                                children: [
                                                    new Y.HtmlElement({
                                                        cssClass: 'col-xs-12 layoutExample',
                                                        htmlContent: '<div class="container-fluid container-fluid-legacy">' +
                                                        '<div class="row-legacy">' +
                                                        '<div class="col-xs-5 col-sm-5 layout-col"></div>' +
                                                        '<div class="col-xs-7 col-sm-7 layout-col"></div>' +
                                                        '</div>'
                                                    })
                                                ]
                                            })
                                        ]
                                    }),
                                    new Y.HtmlElement({
                                        cssClass: 'container-fluid container-fluid-legacy row-legacy',
                                        children: [
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-5 col-sm-5 layout-set-select',
                                                children: [
                                                    new Y.RadioElement({
                                                        label: '2+1',
                                                        value: 'l21',
                                                        modelInstance: instance,
                                                        name: FIELD_LAYOUT
                                                    })
                                                ]
                                            }),
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-7 col-sm-7',
                                                children: [
                                                    new Y.HtmlElement({
                                                        cssClass: 'col-xs-12 col-sm-12 layoutExample',
                                                        htmlContent: '<div class="container-fluid container-fluid-legacy">' +
                                                        '<div class="row-legacy">' +
                                                        '<div class="col-xs-7 col-sm-7 layout-col"></div>' +
                                                        '<div class="col-xs-5 col-sm-5 layout-col"></div>' +
                                                        '</div>'
                                                    })
                                                ]
                                            })
                                        ]
                                    }),
                                    new Y.HtmlElement({
                                        cssClass: 'item-layout-container row-legacy',
                                        children: [
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-5 col-sm-5 layout-set-select',
                                                children: [
                                                    new Y.RadioElement({
                                                        label: instance.t('baseWidgetList.layoutFlexible'),
                                                        value: 'l11f',
                                                        modelInstance: instance,
                                                        name: FIELD_LAYOUT
                                                    })
                                                ]
                                            }),
                                            new Y.HtmlElement({
                                                cssClass: 'col-xs-7 col-sm-7',
                                                children: [
                                                    new Y.HtmlElement({
                                                        cssClass: 'col-xs-12 layoutExample layoutFlexibleExample',
                                                        htmlContent: '<div class="container-fluid container-fluid-legacy">' +
                                                        '<div class="row-legacy">' +
                                                        '<div class="col-xs-' + savedFlexibleRatioCol1 + ' col-sm-' + savedFlexibleRatioCol1 + ' layout-col"></div>' +
                                                        '<div class="col-xs-' + savedFlexibleRatioCol2 + ' col-sm-' + savedFlexibleRatioCol2 + ' layout-col"></div>' +
                                                        '</div>'
                                                    }),
                                                    new Y.HtmlElement({
                                                        cssClass: 'col-xs-12 col-sm-12 layoutFlexibleControls',
                                                        children: [
                                                            new Y.SelectBoxElement({
                                                                cssClass: 'col-xs-6 col-sm-6 layout-flexible-col-selector',
                                                                id: 'layoutFlexibleCol1',
                                                                label: '',
                                                                modelInstance: instance,
                                                                name: FIELD_LAYOUT_FLEXIBLE_RATIO + "_col1",
                                                                options: layoutFlexibleColOptions,
                                                                defaultSelectValue: savedFlexibleRatioCol1,
                                                                onChange: function (e) {
                                                                    var selectedValue = e.target.get('value');
                                                                    instance.setLayoutFlexibleRatio(selectedValue, 12 - selectedValue);
                                                                }
                                                            }),
                                                            new Y.SelectBoxElement({
                                                                cssClass: 'col-xs-6 col-sm-6 layout-flexible-col-selector',
                                                                id: 'layoutFlexibleCol2',
                                                                label: '',
                                                                modelInstance: instance,
                                                                name: FIELD_LAYOUT_FLEXIBLE_RATIO + "_col2",
                                                                options: layoutFlexibleColOptions,
                                                                defaultSelectValue: savedFlexibleRatioCol2,
                                                                onChange: function (e) {
                                                                    var selectedValue = e.target.get('value');
                                                                    instance.setLayoutFlexibleRatio(12 - selectedValue, selectedValue);
                                                                }
                                                            }),
                                                        ]
                                                    })
                                                ]
                                            })
                                        ]
                                    })
                                ]
                            }),
                            new Y.HtmlElement({
                                cssClass: 'col-xs-7 col-sm-7',
                                children: [
                                    new Y.HtmlElement({
                                        cssClass: '',
                                        children: [
                                            new Y.HtmlElement({
                                                cssClass: 'layoutSet',
                                                children: []
                                            })
                                        ]
                                    })
                                ]
                            })
                        ]
                    })
                ]
            });

            return step;
        },

        setLayoutFlexibleRatio: function (col1, col2) {
            var instance = this,
                    host = instance.get('host');

            var html = '<div class="container-fluid container-fluid-legacy">' +
                    '<div class="row-legacy">' +
                    '<div class="col-xs-' + col1 + ' col-sm-' + col1 + ' layout-col"></div>' +
                    '<div class="col-xs-' + col2 + ' col-sm-' + col2 + ' layout-col"></div>' +
                    '</div>';

            host.one('.layoutFlexibleExample').html(html);
            host.one('.layout-flexible-col-selector:first-child').set('value', col1);
            host.one('.layout-flexible-col-selector:last-child').set('value', col2);

            instance.set(FIELD_LAYOUT_FLEXIBLE_RATIO, col1 + '-' + col2);
            instance._layoutSet(true);
            instance._setLayoutMetadata();
        },

        getInputObject: function (objectName, objectLabel, defaultValue, cssClass) {
            var instance = this, inputObj, inputTextBox;
            var objName = (objectName != null) ? objectName : '';
            var objLabel = (objectLabel != null) ? objectLabel : '';
            var defaultVal = (defaultValue != null) ? defaultValue : '';

            inputTextBox = new Y.InputElement({
                name: objName,
                id: objName,
                modelInstance: instance,
                wrapperCssClass: 'setterComponent col-md-12 layout-group-container',
                cssClass: 'col-md-12',
                label: objLabel,
                placeholder: '',
                value: defaultVal,
                onChange: function (e) {
                    instance.updateOptionsInstances(e.target, e.target.get("value"));
                }
            })

            inputObj = new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'col-md-12 layout-group-container ' + (cssClass ? cssClass : ''),
                children: [inputTextBox]
            })


            return inputObj;
        },

        updateBasicAppearance: function (fireObject, value) {
            var instance = this;
            var returnObject = basicAppearance;

            if (returnObject == null || basicAppearance.length == 0) {
                /*  returnObject = { height: 480, width: 480, fontFamily: 'Arial',
                 backgroundColor: '#ffffff', borderWidth: 1, borderColor: '#ffffff'};*/

                returnObject = BASIC_APPEARANCE_DFAULTS;
            }

            if (fireObject == APPEARANCE_BASIC_PREVIEW_HEIGHT) {
                returnObject.height = value;
            }
            if (fireObject == APPEARANCE_BASIC_PREVIEW_WIDTH) {
                returnObject.width = value;
            }
            if (fireObject == APPEARANCE_BASIC_PREVIEW_FONT_FAMILY) {
                returnObject.fontFamily = value;
            }
            if (fireObject == APPEARANCE_BASIC_PREVIEW_BACKGROUND_COLOR) {
                returnObject.backgroundColor = value;
            }
            if (fireObject == APPEARANCE_BASIC_PREVIEW_BORDER_WIDTH) {
                returnObject.borderWidth = value;
            }
            if (fireObject == APPEARANCE_BASIC_PREVIEW_BORDER_COLOR) {
                returnObject.borderColor = value;
            }
            if (fireObject == APPEARANCE_BASIC_PREVIEW_MIN_WIDTH) {
                returnObject.minWidth = value;
            }
            if (fireObject == APPEARANCE_BASIC_PREVIEW_MIN_HEIGHT) {
                returnObject.minHeight = value;
            }

            basicAppearance = returnObject;
        },

        getSettingSelector: function (objectName, objectLabel, defaultValue, componentList, fireObject, objectList, cssClass) {
            var instance = this;
            var fontSelector;
            var objName = (objectName != null) ? objectName : '';
            var objLabel = (objectLabel != null) ? objectLabel : '';
            var defaultVal = (defaultValue != null) ? defaultValue : '';
            var componentList = componentList


            fontSelector = new Y.HtmlElement({
                cssClass: 'col-md-12 layout-group-container',
                wrapperCssClass: 'col-md-12 layout-group-container ' + (cssClass ? cssClass : ''),
                children: [
                    new Y.SelectBoxElement({
                        cssClass: 'col-md-12',
                        wrapperCssClass: 'setterComponent col-md-12 layout-group-container',
                        label: objLabel,
                        modelInstance: instance,
                        defaultSelectValue: defaultVal,
                        name: objName,
                        id: objName,
                        options: componentList,
                        onChange: function (e) {
                            instance.set(e.target.get('name'), e.target.get('value'));
                            if (e.target.get('name') == APPEARANCE_BASIC_PREVIEW_METADATA) {
                                currentAppearanceOption = e.target.get('value');
                            }
                            var properties = e.target.ancestor('.appearance-advanced') ?
                                    e.target.ancestor('.appearance-advanced').all('.advancedAppearanceProperty') : undefined;
                            if (properties && currentAppearanceOption != '' && currentAppearanceOption != 'select') {
                                properties.each(function (property) {
                                    // show maxWidth input only for thumbnail
                                    if (property.hasClass(APPEARANCE_BASIC_PREVIEW_MAX_WIDTH)) {
                                        if (currentAppearanceOption == 'thumbnail') {
                                            property.removeClass('hidden');
                                        }
                                        else {
                                            property.addClass('hidden');
                                        }
                                    }
                                    else {
                                        property.removeClass('hidden');
                                    }
                                });
                            }
                            else if (properties) {
                                properties.each(function (property) {
                                    property.addClass('hidden');
                                });
                            }
                            if (fireObject != null && objectList != null && currentAppearanceOption != 'select') {

                                if (fireObject == APPEARANCE_BASIC_PREVIEW_TITLE_H) {
                                    var returnObject = instance.updateOptionsInstancesSelector(fireObject, e.target.get('value'));
                                }
                                else if (fireObject == APPEARANCE_BASIC_PREVIEW_FONT_FAMILY) {
                                    instance.updateBasicAppearance(fireObject, e.target.get('value'));
                                }
                                else if (fireObject == APPEARANCE_BASIC_PREVIEW_BORDER_WIDTH) {
                                    instance.updateBasicAppearance(fireObject, e.target.get('value'));
                                }
                                else if (fireObject == APPEARANCE_BASIC_PREVIEW_METADATA) {
                                    currentMetaOtion = fireObject;
                                    var returnObject = instance.updateDependentOptions(fireObject, objectList);
                                    var objectToUpdate = null;
                                    var objectToCheck = null;

                                    var foundIndex = undefined;
                                    if (metaDataAppearanceObjs.length > 0) {
                                        for (var j = 0; j < metaDataAppearanceObjs.length; j++) {
                                            if (returnObject.metadata == metaDataAppearanceObjs[j].metadata) {
                                                foundIndex = j;
                                            }
                                        }
                                    }
                                    if (foundIndex != undefined) {
                                        metaDataAppearanceObjs[foundIndex] = returnObject;
                                        for (var z = 0; z < objectList.length; z++) {

                                            objectToUpdate = Y.one("#" + objectList[z].get('children')[0].get('name'));
                                            objectToCheck = objectList[z].get('children')[0].get('name');

                                            if (objectToCheck == APPEARANCE_BASIC_PREVIEW_FONT_SIZE) {
                                                objectToUpdate.set('value', metaDataAppearanceObjs[foundIndex].fontSize);
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_FONT_COLOR) {
                                                objectToUpdate.set('value', metaDataAppearanceObjs[foundIndex].fontColor);
                                                objectToUpdate.simulate('change');
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_MARGIN_WIDTH) {
                                                objectToUpdate.set('value', metaDataAppearanceObjs[foundIndex].margin);
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_PADDING_WIDTH) {
                                                objectToUpdate.set('value', metaDataAppearanceObjs[foundIndex].padding);
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_TITLE_H) {
                                                var optionList = Y.all("#" + objectList[z].get('children')[0].get('name') + " option");
                                                optionList = optionList.get("nodes");
                                                if (optionList != null && optionList.length > 0) {
                                                    if (!metaDataAppearanceObjs[foundIndex].htmlElement) {
                                                        metaDataAppearanceObjs[foundIndex].htmlElement = '';
                                                    }
                                                    for (var t = 0; t < optionList.length; t++) {
                                                        if (optionList[t].get('value') == metaDataAppearanceObjs[foundIndex].htmlElement) {
                                                            optionList[t].set('selected', true);
                                                        }

                                                    }
                                                }
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_MAX_WIDTH) {
                                                objectToUpdate.set('value', metaDataAppearanceObjs[foundIndex].maxWidth ? metaDataAppearanceObjs[foundIndex].maxWidth : '');
                                            }
                                        }
                                    }
                                    else { // index not found, creating new entry in metaDataAppearanceObjs
                                        for (var z = 0; z < objectList.length; z++) {

                                            objectToUpdate = Y.one("#" + objectList[z].get('children')[0].get('name'));
                                            objectToCheck = objectList[z].get('children')[0].get('name');

                                            if (objectToCheck == APPEARANCE_BASIC_PREVIEW_FONT_SIZE) {
                                                objectToUpdate.set('value', BASIC_APPEARANCE_DFAULTS.fontSize);
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_FONT_COLOR) {
                                                objectToUpdate.set('value', BASIC_APPEARANCE_DFAULTS.fontColor);
                                                objectToUpdate.simulate('change');
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_MARGIN_WIDTH) {
                                                objectToUpdate.set('value', BASIC_APPEARANCE_DFAULTS.marginWidth);
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_PADDING_WIDTH) {
                                                objectToUpdate.set('value', BASIC_APPEARANCE_DFAULTS.paddingWidth);
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_TITLE_H) {
                                                var optionList = Y.all("#" + objectList[z].get('children')[0].get('name') + " option");
                                                optionList.get("nodes")[0].set('selected', true);
                                            }
                                            else if (objectToCheck == APPEARANCE_BASIC_PREVIEW_MAX_WIDTH) {
                                                objectToUpdate.set('value', BASIC_APPEARANCE_DFAULTS.maxWidth ? BASIC_APPEARANCE_DFAULTS.maxWidth : '');
                                            }
                                        }
                                        metaDataAppearanceObjs.push(returnObject);
                                    }
                                }
                            }
                        }
                    })
                ]
            })

            return fontSelector
        },

        getAdvancedAppearenceMetaDataObjectList: function () {
            return metaDataAppearanceObjs;
        },

        /**
         * This method will apply all the saved data for Advanced Appearance objects.
         */
        initAdvancedAppearanceCSS: function () {
            var instance = this;
            var advancedTextAreaNode = Y.one("#" + FIELD_ADVANCED_SET_APPEARANCE);
            var existingStyle = advancedTextAreaNode.get('value');
            advancedTextAreaNode.set('value', '');

            instance.convertBasicAppearanceObjListToJson();
            instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());

            var advancedAppearanceRequest = {
                widgetAppearance: instance.get('widgetAppearance'),
                metadataAppearanceList: instance.get('metadataAppearanceList'),
                existingStyle: existingStyle
            }

            Y.io(ADVANCED_APPEARANCE_URL, {
                method: 'POST',
                data: Y.JSON.stringify(advancedAppearanceRequest),
                headers: {
                    'Content-Type': 'application/json'
                },
                on: {
                    success: function (id, response) {
                        var advancedCss = response.response.split('\\r').join('').split('"').join('').split('\\t').join('  ').split('\\n').join('\n');
                        advancedTextAreaNode.set('value', advancedCss);
                        instance.set(FIELD_ADVANCED_SET_APPEARANCE, advancedCss);
                    },
                    error: function (response) {
                    }
                }
            });
        },

        /**
         * This method will transform advanced appearance css to basic appearance objects
         */
        advancedToBasicAppearanceCSS: function () {
            var instance = this;
            var host = instance.get('host');
            var advancedAppearanceCSS = host.one('#' + FIELD_ADVANCED_SET_APPEARANCE).get('value');
            instance.set(FIELD_ADVANCED_SET_APPEARANCE, advancedAppearanceCSS);
            if (!advancedAppearanceCSS || advancedAppearanceCSS.length <= 0) {
                return;
            }
            var metadataSelect = host.one('#' + APPEARANCE_BASIC_PREVIEW_METADATA);
            var metadataProperties = host.all('.' + ADVANCED_APPEARANCE_PROPERTY);
            if (metadataSelect) {
                metadataSelect.set('value', '');
            }
            if (metadataProperties) {
                metadataProperties.addClass('hidden');
            }

            Y.io(BASIC_APPEARANCE_URL, {
                method: 'POST',
                data: Y.JSON.stringify(advancedAppearanceCSS),
                headers: {
                    'Content-Type': 'application/json'
                },
                on: {
                    success: function (id, response) {
                        var responseData = JSON.parse(response.responseText);
                        instance.applyAdvancedCssToBasicFields(responseData.widgetAppearance);
                        instance.applyAdvancedCssToBasicMetadata(responseData.metadataAppearanceList);
                    },
                    error: function (response) {
                    }
                }
            });
        },

        applyAdvancedCssToBasicFields: function (widgetAppearance) {
            var host = this.get('host');
            if (widgetAppearance) {
                if (widgetAppearance.backgroundColor) {
                    var backgroundColorInput = host.one('#backgroundColor');
                    backgroundColorInput.set('value', widgetAppearance.backgroundColor);
                    backgroundColorInput.simulate('change');
                }
                if (widgetAppearance.borderColor) {
                    var borderColorInput = host.one('#borderColor');
                    borderColorInput.set('value', widgetAppearance.borderColor);
                    borderColorInput.simulate('change');
                }
                if (widgetAppearance.fontFamily) {
                    var valueExists = false;
                    var fontFamilySelector = host.one('#fontFamily');
                    fontFamilySelector.all('option').each(function (option) {
                        if (option.get('value') == widgetAppearance.fontFamily) {
                            valueExists = true;
                        }
                    });
                    if (!valueExists) {
                        fontFamilySelector.append(Y.Node.create('<option value="' + widgetAppearance.fontFamily + '">' + widgetAppearance.fontFamily + '</option>'));
                    }
                    fontFamilySelector.set('value', widgetAppearance.fontFamily);

                }
                if (widgetAppearance.borderWidth) {

                    var valueExists = false;
                    var borderWidthSelector = host.one('#borderWidth');
                    borderWidthSelector.all('option').each(function (option) {
                        if (option.get('value') == widgetAppearance.borderWidth) {
                            valueExists = true;
                        }
                    });
                    if (!valueExists) {
                        borderWidthSelector.append(Y.Node.create('<option value="' + widgetAppearance.borderWidth + '">' + widgetAppearance.borderWidth + '</option>'));
                    }
                    borderWidthSelector.set('value', widgetAppearance.borderWidth);
                }
                if (widgetAppearance.minHeight || widgetAppearance.minWidth == 0) {
                    host.one('#minHeight').set('value', widgetAppearance.minHeight);
                    host.one('#minHeight').simulate('change');
                }
                if (widgetAppearance.minWidth || widgetAppearance.minWidth == 0) {
                    host.one('#minWidth').set('value', widgetAppearance.minWidth);
                    host.one('#minWidth').simulate('change');
                }
                if (widgetAppearance.width || widgetAppearance.minWidth == 0) {
                    host.one('#width').set('value', widgetAppearance.width);
                    host.one('#width').simulate('change');
                }
                if (widgetAppearance.height || widgetAppearance.minWidth == 0) {
                    host.one('#height').set('value', widgetAppearance.height);
                    host.one('#height').simulate('change');
                }
            }
        },

        applyAdvancedCssToBasicMetadata: function (metadataAppearance) {
            var host = this.get('host');
            var metadataSelect = host.one('#' + APPEARANCE_BASIC_PREVIEW_METADATA);
            var metadataProperties = host.all('.' + ADVANCED_APPEARANCE_PROPERTY);
            if (!metadataAppearance || !metadataSelect || !metadataProperties) {
                return;
            }
            if(metadataAppearance.length === 0){
                metaDataAppearanceObjs = [];
            }
            for (var i = 0; i < metaDataAppearanceObjs.length; i++) {
                var objectExists = false;
                if (metaDataAppearanceObjs[i] && metaDataAppearanceObjs[i].metadata) {
                    for (var j = 0; j < metadataAppearance.length; j++) {
                        if (metaDataAppearanceObjs[i].metadata == metadataAppearance[j].metadataKey) {
                            objectExists = true;
                            if (metadataAppearance[j].fontColor) {
                                metaDataAppearanceObjs[i].fontColor = metadataAppearance[j].fontColor;
                            }
                            if (metadataAppearance[j].fontSize) {
                                metaDataAppearanceObjs[i].fontSize = metadataAppearance[j].fontSize;
                            }
                            if (metadataAppearance[j].htmlElement) {
                                metaDataAppearanceObjs[i].htmlElement = metadataAppearance[j].htmlElement;
                            }
                            if (metadataAppearance[j].margin) {
                                metaDataAppearanceObjs[i].margin = metadataAppearance[j].margin;
                            }
                            if (metadataAppearance[j].padding) {
                                metaDataAppearanceObjs[i].padding = metadataAppearance[j].padding;
                            }
                        }
                    }
                }
                if (!objectExists) {
                    metaDataAppearanceObjs.splice(i,1);
                    i--;
                }
            }
        },


        /**
         * Render the MetaData option Objec list to the Wrapper DIV
         * @param destinationOBJ - Wrapper DIV
         * @param metadataBoxOptions - Selected MetaData's
         */
        renderMetaBojects: function (destinationOBJ, metadataBoxOptions) {
            var instance = this;
            destinationOBJ.empty();

            if (metadataBoxOptions != null && metadataBoxOptions.size() > 0) {
                metadataBoxOptions.each(function (e) {
                    var valType = this.get(ELEM_ATTR.VALUE);
                    for (var i = 0; i < METADATA_SELECTION_OBJS.length; i++) {
                        if (METADATA_SELECTION_OBJS[i].get(ELEM_ATTR.VALUE) == valType) {
                            try {
                                //Renders the object int
                                destinationOBJ.append(METADATA_SELECTION_OBJS[i].render());
                            } catch (e) {
                                console.log('error', e);
                            }
                        }
                    }
                })
            }
        },

        /**
         * Converts the Basic Appearance object in JSON Obj
         * Assigns the generated object to widgetAppearance paramater
         */
        convertBasicAppearanceObjListToJson: function () {
            var genObj = {
                'minHeight': '0',
                'minWidth': '0',
                'fontFamily': 'Helvetica',
                'backgroundColor': '#ffffff',
                'borderWidth': '1',
                'borderColor': '#d3d3d3',
                'width': '0',
                'height': '0'
            };
            var host = this.get('host');
            var backgroundColorInput = host.one('#backgroundColor');
            var borderColorInput = host.one('#borderColor');
            var fontFamilyInput = host.one('#fontFamily');
            var borderWidthInput = host.one('#borderWidth');
            var minHeightInput = host.one('#minHeight');
            var minWidthInput = host.one('#minWidth');
            var widthInput = host.one('#width');
            var heightInput = host.one('#height');

            if (backgroundColorInput && backgroundColorInput.get('value') && !(backgroundColorInput.get('value') === '#')) {
                genObj.backgroundColor = backgroundColorInput.get('value');
            }
            if (borderColorInput && borderColorInput.get('value') && !(borderColorInput.get('value') === '#')) {
                genObj.borderColor = borderColorInput.get('value');
            }
            if (fontFamilyInput && fontFamilyInput.get('value')) {
                genObj.fontFamily = fontFamilyInput.get('value');
            }
            if (borderWidthInput && borderWidthInput.get('value')) {
                genObj.borderWidth = borderWidthInput.get('value');
            }
            if (minHeightInput && minHeightInput.get('value')) {
                genObj.minHeight = minHeightInput.get('value');
            }
            if (minWidthInput && minWidthInput.get('value')) {
                genObj.minWidth = minWidthInput.get('value');
            }
            if (widthInput && widthInput.get('value')) {
                genObj.width = widthInput.get('value');
            }
            if (heightInput && heightInput.get('value')) {
                genObj.height = heightInput.get('value');
            }

            this.set('widgetAppearance', genObj);
        },

        /**
         * Converts the metadata object list in to a list of json objects.
         * @param metadataAppearanceObjList
         */
        convertBasicAppearanceMetaObjListToJson: function (metadataAppearanceObjList) {
            var genObjList = [];

            for (var i = 0; i < metadataAppearanceObjList.length; i++) {
                if ((childObject = metadataAppearanceObjList[i]) != null) {
                    genObjList.push({
                        'metadataKey': childObject.metadata,
                        'htmlElement': childObject.htmlElement,
                        'fontSize': childObject.fontSize,
                        'fontColor': childObject.fontColor,
                        'margin': childObject.margin,
                        'padding': childObject.padding,
                        'maxWidth': childObject.maxWidth ? childObject.maxWidth : ''
                    })

                }
            }

            this.set('metadataAppearanceList', genObjList);
        },

        /**
         * Retruns the mtedata translated
         * @returns {Array}
         */
        getMetadataTranslation: function () {
            var instance = this, options = [], i;

            for (i = 0; i < METADATA.length; i++) {
                options.push({
                    key: METADATA[i].key,
                    value: instance.t('baseWidgetList.' + METADATA[i].key)
                })
            }
            return options;
        },

        convertLayoutStyleToJson: function () {
            var genObj = {
                'slidesNumber': '',
                'timing': '',
                'transition': '',
                'controls': '',
                'columns': ''

            }


            var chids = slideShowLayout.get('children')[1].get('children')[1].get('children');

            if (chids != null && chids.length > 0) {
                genObj.slidesNumber = this.get(chids[0].get('name'));
                genObj.timing = this.get(chids[1].get('name'));
                genObj.transition = this.get(chids[2].get('name'));
                genObj.controls = this.get(chids[3].get('name'));
                genObj.columns = this.get(chids[4].get('name'));
            }


            this.set('slideShowLayout', genObj);
        },

        updateOptionsInstances: function (fireObject, objectValue) {
            if (currentAppearanceOption != null && currentAppearanceOption.length > 0) {
                if (metaDataAppearanceObjs.length > 0) {
                    for (var j = 0; j < metaDataAppearanceObjs.length; j++) {
                        if (currentAppearanceOption == metaDataAppearanceObjs[j].id) {
                            if (metaDataAppearanceObjs[j] != null) {
                                if (fireObject.get('name') == APPEARANCE_BASIC_PREVIEW_FONT_SIZE) {
                                    metaDataAppearanceObjs[j].fontSize = objectValue;
                                }
                                else if (fireObject.get('name') == APPEARANCE_BASIC_PREVIEW_FONT_COLOR) {
                                    metaDataAppearanceObjs[j].fontColor = objectValue;
                                }
                                else if (fireObject.get('name') == APPEARANCE_BASIC_PREVIEW_MARGIN_WIDTH) {
                                    metaDataAppearanceObjs[j].margin = objectValue;
                                }
                                else if (fireObject.get('name') == APPEARANCE_BASIC_PREVIEW_PADDING_WIDTH) {
                                    metaDataAppearanceObjs[j].padding = objectValue;
                                }
                                else if (fireObject.get('name') == APPEARANCE_BASIC_PREVIEW_TITLE_H) {
                                    metaDataAppearanceObjs[j].htmlElement = objectValue;
                                }
                                else if (fireObject.get('name') == APPEARANCE_BASIC_PREVIEW_MAX_WIDTH) {
                                    metaDataAppearanceObjs[j].maxWidth = objectValue ? objectValue : '';
                                }
                            }
                        }
                    }
                }
            }
        },

        updateOptionsInstancesSelector: function (fireObject, objectValue) {
            var instance = this;
            var returnObject = null;

            if (currentMetaOtion != null && currentMetaOtion.length > 0) {
                if (metaDataAppearanceObjs.length > 0) {
                    for (var j = 0; j < metaDataAppearanceObjs.length; j++) {
                        if (instance.get(currentMetaOtion) == metaDataAppearanceObjs[j].id) {
                            returnObject = metaDataAppearanceObjs[j];
                            if (returnObject != null) {
                                if (fireObject == APPEARANCE_BASIC_PREVIEW_TITLE_H) {
                                    returnObject.htmlElement = objectValue;

                                }
                            }
                            metaDataAppearanceObjs[j] = returnObject;
                            return returnObject;
                            break;
                        }
                    }

                }
            }

            return returnObject;
        },

        /**
         *
         * @param fireObject = Object name - the object thats need to be updated
         * @param objectList - list of objects
         * @returns {*}
         */
        updateDependentOptions: function (fireObject, objectList) {
            var instance = this;
            var returnObject = null;

            if (metaDataAppearanceObjs.length > 0) {
                for (var j = 0; j < metaDataAppearanceObjs.length; j++) {
                    if (instance.get(fireObject) == metaDataAppearanceObjs[j].metadata) {
                        returnObject = metaDataAppearanceObjs[j];
                        return returnObject;
                    }
                }
            }

            for (var i = 0; i < objectList.length; i++) {

                if (returnObject == null) {
                    returnObject = {
                        metadata: '', htmlElement: '', fontSize: 0,
                        fontColor: '', margin: 0, padding: 0, id: ''
                    };
                }

                if (objectList[i].get('children')) {

                    if (fireObject == objectList[i].get('children')[0].get('name') && fireObject == APPEARANCE_BASIC_PREVIEW_METADATA) {
                        returnObject.metadata = instance.get(objectList[i].get('children')[0].get('name'));
                        returnObject.id = instance.get(objectList[i].get('children')[0].get('name'));
                    }
                    else {

                        if (objectList[i].get('children')[0] instanceof Y.SelectBoxElement &&
                                objectList[i].get('children')[0].get('name') == APPEARANCE_BASIC_PREVIEW_TITLE_H) {
                            returnObject.htmlElement = this.get(objectList[i].get('children')[0].get('name'));

                        }

                        if (objectList[i].get('children')[0] instanceof Y.InputElement) {
                            if (objectList[i].get('children')[0].get('name') == APPEARANCE_BASIC_PREVIEW_FONT_SIZE) {
                                returnObject.fontSize = objectList[i].get('children')[0].get('value');
                            }

                            if (objectList[i].get('children')[0].get('name') == APPEARANCE_BASIC_PREVIEW_FONT_COLOR) {
                                returnObject.fontColor = objectList[i].get('children')[0].get('value');
                            }

                            if (objectList[i].get('children')[0].get('name') == APPEARANCE_BASIC_PREVIEW_MARGIN_WIDTH) {
                                returnObject.margin = objectList[i].get('children')[0].get('value');
                            }

                            if (objectList[i].get('children')[0].get('name') == APPEARANCE_BASIC_PREVIEW_PADDING_WIDTH) {
                                returnObject.padding = objectList[i].get('children')[0].get('value');
                            }

                            if (objectList[i].get('children')[0].get('name') == APPEARANCE_BASIC_PREVIEW_METADATA) {
                                returnObject.id = objectList[i].get('children')[0].get('value');
                            }
                        }
                    }

                }

            }

            return returnObject;
        },

        /**
         * @deprecated
         * @method getLayoutStep
         * @return {PanelElement} a panel with layout style selection
         */
        getLayoutStyleStep_d: function () {
            var instance = this,
                    step,
                    columnsOptions = [1, 2, 3, 4, 6, 12],
                    rowsOptions = [],
                    i;

            for (i = 1; i <= RESTRICTION_MAX_ROWS; i++) {
                rowsOptions.push(i);
            }

            step = new Y.PanelElement({
                label: instance.t('baseWidgetList.layoutStyle'),
                children: [
                    new Y.HtmlElement({
                        cssClass: 'container-fluid container-fluid-legacy',
                        children: [
                            new Y.HtmlElement({
                                cssClass: 'row-legacy layout-style',
                                children: [
                                    new Y.HtmlElement({
                                        'cssClass': 'col-xs-5 col-sm-5',
                                        children: [
                                            new Y.RadioElement({
                                                label: instance.t('baseWidgetList.stylePaginated'),
                                                value: STYLE_PAGINATED,
                                                modelInstance: instance,
                                                name: FIELD_LAYOUT_STYLE
                                            }),
                                            new Y.HtmlElement({
                                                'cssClass': 'pagination-options',
                                                children: [
                                                    new Y.SelectBoxElement({
                                                        label: instance.t('baseWidgetList.columns'),
                                                        modelInstance: instance,
                                                        name: FIELD_COLUMNS,
                                                        options: columnsOptions
                                                    }),
                                                    new Y.SelectBoxElement({
                                                        label: instance.t('baseWidgetList.rows'),
                                                        modelInstance: instance,
                                                        name: FIELD_ROWS,
                                                        options: rowsOptions
                                                    })
                                                ]
                                            })
                                        ]
                                    }),
                                    new Y.HtmlElement({
                                        'cssClass': 'col-xs-7 col-sm-7',
                                        children: [
                                            new Y.RadioElement({
                                                label: instance.t('baseWidgetList.slideShow'),
                                                value: STYLE_SLIDE_SHOW,
                                                modelInstance: instance,
                                                name: FIELD_LAYOUT_STYLE,
                                                disabled: true
                                            }),
                                            new Y.HtmlElement({
                                                'cssClass': 'pagination-options',
                                                children: [
                                                    //add options here
                                                ]
                                            })
                                        ]
                                    })
                                ]
                            })
                        ]
                    })
                ]
            });

            return step;
        },


        /**
         * Executes the regex to get the cellar id from publication permanent link
         *
         * @method _getCellarId
         * @param content
         * @return String
         * @private
         */
        _getCellarId: function (content) {
            try {
                CELLAR_REGEX.lastIndex = 0;
                var match = CELLAR_REGEX.exec(content);
                return match[0];
            } catch (exception) {
                return undefined;
            }
        },

        getShareThisSelector: function () {
            var instance = this;
            var selector;

            selector = new Y.HtmlElement({
                cssClass: 'row',
                children: [
                    new Y.CheckboxElement({
                        label: instance.t('baseWidgetList.sharethis'),
                        wrapperCssClass: 'col-md-12 check',
                        checked: (instance.getAttrs().showSharePublicationButton ? true : false),
                        modelInstance: instance,
                        id: FIELD_SHARE_THIS,
                        onClick: function () {
                            if (!instance.getAttrs().showSharePublicationButton) {
                                instance.set("showSharePublicationButton", true);
                            }
                            else {
                                instance.set("showSharePublicationButton", false);
                            }
                        }

                    })
                ]
            });

            return selector;

        },

        getOrderThisSelector: function () {
            var instance = this;
            var selector;

            selector = new Y.HtmlElement({
                cssClass: 'row',
                children: [
                    new Y.CheckboxElement({
                        label: instance.t('baseWidgetList.orderthis'),
                        wrapperCssClass: 'col-md-12 check',
                        checked: (instance.getAttrs().showOrderPublicationButton ? true : false),
                        modelInstance: instance,
                        id: FIELD_ORDER_THIS,
                        onClick: function () {
                            if (!instance.getAttrs().showOrderPublicationButton) {
                                instance.set("showOrderPublicationButton", true);
                            }
                            else {
                                instance.set("showOrderPublicationButton", false);
                            }
                        }

                    })
                ]
            });

            return selector;

        },

        getUseDefaultThumbnailImageSelector: function () {
            var instance = this;
            return new Y.HtmlElement({
                cssClass: 'col-md-9 row',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('baseWidgetList.ifThereIsNoThumbnail'),
                        wrapperCssClass: 'col-md-4',
                    }),
                    new Y.RadioElement({
                        label: instance.t('baseWidgetList.useDefaultThumbnailImage'),
                        wrapperCssClass: 'col-md-5',
                        value: true,
                        checked: instance.get("useDefaultThumbnailImage") ? true : false,
                        modelInstance: instance,
                        name: "useDefaultThumbnailImage",
                        onClick: function () {
                            instance.set("useDefaultThumbnailImage", true);
                        }
                    }),
                    new Y.RadioElement({
                        label: instance.t('baseWidgetList.leaveItEmpty'),
                        wrapperCssClass: 'col-md-3',
                        value: false,
                        checked: instance.get("useDefaultThumbnailImage") ? false : true,
                        modelInstance: instance,
                        name: "useDefaultThumbnailImage",
                        onClick: function () {
                            instance.set("useDefaultThumbnailImage", false);
                        }
                    }),
                ]
            });
        },

        getShowOnlySelectedLanguagePublicationsSelector: function () {
            var instance = this;
            return new Y.HtmlElement({
                cssClass: 'row',
                children: [
                    new Y.CheckboxElement({
                        label: instance.t('baseWidgetList.showOnlySelectedLanguagePublications'),
                        wrapperCssClass: 'col-md-12 check',
                        checked: instance.getAttrs().showOnlySelectedLanguagePublications ? true : false,
                        modelInstance: instance,
                        id: FIELD_SHOW_ONLY_SELECTED_LANGUAGE_PUBLICATIONS,
                        onClick: function () {
                            if (!instance.getAttrs().showOnlySelectedLanguagePublications) {
                                instance.set("showOnlySelectedLanguagePublications", true);
                            }
                            else {
                                instance.set("showOnlySelectedLanguagePublications", false);
                            }
                        }
                    })
                ]
            });
        },

        getViewThisSelector: function () {
            var instance = this;
            var selector;

            selector = new Y.HtmlElement({
                cssClass: 'form-group pfrm col-md-12',
                children: [
                    new Y.CheckboxElement({
                        label: instance.t('baseWidgetList.viewthis'),
                        wrapperCssClass: 'col-md-4 check',
                        checked: (instance.getAttrs().showViewPublicationButton ? true : false),
                        modelInstance: instance,
                        id: FIELD_VIEW_THIS,
                        onClick: function () {
                            if (!instance.getAttrs().showViewPublicationButton) {
                                instance.set("showViewPublicationButton", true);
                            }
                            else {
                                instance.set("showViewPublicationButton", false);
                            }
                        }

                    })
                ]
            });

            return selector;
        },


        /**
         * @method getLayoutStep
         * @return {PanelElement} a panel with layout style selection
         */
        getLayoutStyleStep: function (configuration) {
            var instance = this,
                    step, i;

            var rowsOptions = [],
                    columnsOptions = [],
                    slideShowSlidesNo = [],
                    slideShowTiming = [],
                    //slideShowEffect = ['basic', 'fade', 'parallax','book'], //Not implemented yet
                    slideShowEffect = ['basic', 'fade'],
                    slideShowControls = ['bullets', 'right and left arrows'],
                    slideColumnSlidesNo = [],
                    tempColumnNo = 1, tempRowsNo = 1,
                    showControlsDefault = slideShowControls[0],
                    showColumnsDefault = 5,
                    timingDefault = 6,
                    effectsDefault = slideShowEffect[0],
                    slideNoDefault = 0;
            if(instance.get('layoutColumns') && instance.get('layoutColumns') > 0) {
                tempColumnNo = instance.get('layoutColumns');
            }
            if(instance.get('layoutRows') && instance.get('layoutRows') > 0) {
                tempRowsNo = instance.get('layoutRows');
            }
            for (i = 1; i <= RESTRICTION_MAX_COLUMNS; i++) {
                columnsOptions.push(i)
            }

            for (i = 1; i <= RESTRICTION_MAX_ROWS; i++) {
                rowsOptions.push(i);
            }

            for (i = 1; i <= NUMBER_OF_SLIDES; i++) {
                slideShowSlidesNo.push(i);
            }

            slideShowTiming.push("0");
            for (i = 1; i <= SLIDE_SHOW_TIMING; i++) {
                slideShowTiming.push(i);
            }

            for (i = 1; i <= NUMBER_OF_COLUMNS; i++) {
                slideColumnSlidesNo.push(i);
            }

            if (configuration != undefined && configuration != null) {
                showControlsDefault = configuration.controls;
                timingDefault = configuration.timing;
                effectsDefault = configuration.transition;
                slideNoDefault = configuration.slidesNumber;
            }

            if(instance._getFullType().includes('PublicationViewWidgetWizard')){
                var messageToShow = new Y.HtmlElement({
                    wrapperCssClass: 'pagination-options-group hidden alert alert-warning message-to-show',
                    cssClass: 'pagination-options',
                    htmlContent: instance.t('selectedPublications.max.results')
                });
            } else {
                var messageToShow = new Y.HtmlElement({
                    wrapperCssClass: 'pagination-options-group hidden alert alert-warning message-to-show',
                    cssClass: 'pagination-options',
                    htmlContent: instance.t('searchResult.max.results')
                });
            }


            /**
             * Widget display, pagination and slide
             * @type {Y.HtmlElement}
             */
            step = new Y.HtmlElement({
                cssClass: 'row-legacy layout-style col-md-12',
                wrapperCssClass: 'widget-display-options col-md-12',
                label: 'Widgets display',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'col-md-5',
                        children: [
                            new Y.RadioElement({
                                label: instance.t('baseWidgetList.stylePaginated'),
                                value: STYLE_PAGINATED,
                                modelInstance: instance,
                                name: FIELD_LAYOUT_STYLE
                            }),
                            /**
                             * Pagination options
                             */
                            new Y.HtmlElement({
                                wrapperCssClass: 'pagination-options-group',
                                cssClass: 'pagination-options',
                                children: [
                                    new Y.SelectBoxElement({
                                        cssClass: 'col-md-12',
                                        label: instance.t('baseWidgetList.columns'),
                                        modelInstance: instance,
                                        name: FIELD_COLUMNS,
                                        options: columnsOptions,
                                        onChange: function (e) {
                                            tempColumnNo = parseInt(e.target.get('value'));
                                            /**
                                             * Show message in case of (cols*rows) > 50
                                             */
                                            if ((tempColumnNo * tempRowsNo) > 50 &&
                                                    messageToShow.render().hasClass('hidden')) {
                                                Y.one(".message-to-show").removeClass('hidden');
                                            }
                                            else {
                                                Y.one(".message-to-show").addClass('hidden');
                                            }
                                            instance.set('layoutColumns', tempColumnNo)
                                            instance.validateWidget();

                                        }
                                    }),
                                    new Y.SelectBoxElement({
                                        cssClass: 'col-md-12',
                                        label: instance.t('baseWidgetList.rows'),
                                        modelInstance: instance,
                                        name: FIELD_ROWS,
                                        options: rowsOptions,
                                        onChange: function (e) {
                                            tempRowsNo = parseInt(e.target.get('value'));
                                            /**
                                             * Show message in case of (cols*rows) > 50
                                             */
                                            if ((tempColumnNo * tempRowsNo) > 50 &&
                                                    messageToShow.render().hasClass('hidden')) {
                                                Y.one(".message-to-show").removeClass('hidden');
                                            }
                                            else {
                                                Y.one(".message-to-show").addClass('hidden');
                                            }
                                            instance.set('layoutRows', tempRowsNo)
                                            instance.validateWidget();
                                        }
                                    })
                                ]
                            }),
                            messageToShow
                        ]
                    }),

                    /**
                     *  Slide show opption
                     */

                    new Y.HtmlElement({
                        cssClass: 'col-md-6 slide-option-group',
                        children: [
                            new Y.RadioElement({
                                label: instance.t('baseWidgetList.slideShow'),
                                value: STYLE_SLIDE_SHOW,
                                modelInstance: instance,
                                name: FIELD_LAYOUT_STYLE,
                                disabled: false
                            }),
                            new Y.HtmlElement({
                                cssClass: 'slide-options',
                                children: [
                                    new Y.SelectBoxElement({
                                        cssClass: 'col-md-12',
                                        label: instance.t('baseWidgetList.slideno'),
                                        modelInstance: instance,
                                        name: FIELD_SLIDE_SHOW_NUMBER_SLIDES,
                                        options: slideShowSlidesNo,
                                        defaultSelectValue: slideNoDefault,
                                        onChange: function (e) {
                                            instance.set(FIELD_SLIDE_SHOW_NUMBER_SLIDES, e.target.get('value'))
                                        }
                                    }),
                                    new Y.SelectBoxElement({
                                        cssClass: 'col-md-12',
                                        label: instance.t('baseWidgetList.timing'),
                                        modelInstance: instance,
                                        name: FIELD_SLIDE_SHOW_TIMING,
                                        options: slideShowTiming,
                                        defaultSelectValue: timingDefault,
                                        onChange: function (e) {
                                            instance.set(FIELD_SLIDE_SHOW_TIMING, e.target.get('value'))
                                        }
                                    }),
                                    new Y.SelectBoxElement({
                                        cssClass: 'col-md-12',
                                        label: instance.t('baseWidgetList.transition'),
                                        modelInstance: instance,
                                        name: FIELD_SLIDE_SHOW_EFFECT,
                                        options: slideShowEffect,
                                        defaultSelectValue: effectsDefault,
                                        onChange: function (e) {
                                            instance.set(FIELD_SLIDE_SHOW_EFFECT, e.target.get('value'))
                                        }
                                    }),
                                    new Y.SelectBoxElement({
                                        cssClass: 'col-md-12',
                                        label: instance.t('baseWidgetList.controls'),
                                        modelInstance: instance,
                                        name: FIELD_SLIDE_SHOW_CONTROLS,
                                        options: slideShowControls,
                                        defaultSelectValue: showControlsDefault,
                                        onChange: function (e) {
                                            instance.set(FIELD_SLIDE_SHOW_CONTROLS, e.target.get('value'))
                                        }
                                    }),
                                    new Y.SelectBoxElement({
                                        cssClass: 'col-md-12',
                                        label: instance.t('baseWidgetList.columns'),
                                        modelInstance: instance,
                                        name: FIELD_SLIDE_SHOW_COLUMNS,
                                        options: slideColumnSlidesNo,
                                        defaultSelectValue: showColumnsDefault,
                                        onChange: function (e) {
                                            instance.set(FIELD_SLIDE_SHOW_COLUMNS, e.target.get('value'))
                                        }
                                    }),
                                ]
                            })
                        ]
                    })
                ]
            });

            slideShowLayout = step;
            return step;
        },

        getTargetPageStep: function () {
            var instance = this;
            var targetPageStep = new Y.HtmlElement({
                label: instance.t('baseWidgetList.targetPage'),
                cssClass: 'container',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'row',
                        children: [
                            new Y.RadioElement({
                                label: instance.t('baseWidgetList.targetPage.euLawAndPublicationsWebsite'),
                                value: RESULTS_PAGE_EU_LAW,
                                modelInstance: instance,
                                name: FIELD_RESULTS_PAGE
                            })
                        ]
                    }),
                    new Y.HtmlElement({
                        cssClass: 'row',
                        children: [
                            new Y.RadioElement({
                                label: instance.t('baseWidgetList.targetPage.ownWebsite'),
                                value: RESULTS_PAGE_OWN,
                                modelInstance: instance,
                                name: FIELD_RESULTS_PAGE,
                                id: instance.get('namespace') + "_" + FIELD_RESULTS_PAGE,
                                wrapperCssClass: ''
                            }),
                            new Y.InputElement({
                                modelInstance: instance,
                                name: FIELD_TARGET_PAGE,
                                wrapperCssClass: 'col-md-9',
                                onClick: function () {
                                    Y.one("#" + instance.get('namespace') + "_" + FIELD_RESULTS_PAGE)
                                            .set('checked', true);
                                }
                            })
                        ]
                    })
                ]
            });
            return targetPageStep;
        },

        clearCache: function () {
            var instance = this;
            var clearCacheUrl = Liferay.portal2012[instance.get('namespace') + "clearCacheUrl"];

            Y.io.request(clearCacheUrl, {
                method: 'POST',
                on: {
                    success: function () {

                    }
                }
            });
        },

        getWidgetStatistics: function () {
            var instance = this;
            var widgetStatisticsURL = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsURL"]
            console.log(widgetStatisticsURL);
        },

        getTemplatesButtonBar: function () {
            var instance = this, buttons = [];
            var templatesButton = new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right',
                htmlContent: instance.t('baseWidgetList.templates') + ' <span class="icon-chevron-down"></span>',
                onClick: function (e) {
                    instance.openTemplateMenu(instance, e.target);
                }
            });

            buttons.push(templatesButton);
            return buttons;
        },

        createTemplateElement: function (instance, template, isApplied, upgradeEnabled, removeEnabled) {
            var checkColumnClass = isApplied ? '' : 'hidden';
            const templateId = template.id;
            const templateName = template.name;
            const templateUser = template.user;

            var currentTemplateHtml = '<li class="widget-template-element" id="widgetTemplate_' + templateId + '" data-user="' + templateUser + '">';
            currentTemplateHtml += '<span class="template-check-control"><i class="icon-check w-check-template w-check-template-' + templateId + ' ' + checkColumnClass + '"></i></span>';
            currentTemplateHtml += '<span class="template-name select-template" templateId="' + templateId + '" title="' + instance.t('baseWidgetList.templates.applyTemplate') + '">' + templateName + '</span>';

            currentTemplateHtml += '<span class="template-controls">';
            if (upgradeEnabled) {
                currentTemplateHtml += '<i class="icon-flag upgrade-template" title="' + instance.t('baseWidgetList.templates.upgradeTemplate') + '" templateId="' + templateId + '" ></i>';
            }
            if (removeEnabled) {
                currentTemplateHtml += '<i class="icon-remove remove-template" title="' + instance.t('baseWidgetList.templates.removeTemplate') + '" templateId="' + templateId + '" ></i>';
            }
            currentTemplateHtml += '</span>';

            currentTemplateHtml += '</li>';
            return currentTemplateHtml;
        },

        openTemplateMenu: function (instance, targetElement) {
            var templateList = instance.get('templateList');
            if (!templateList) {
                var isAdmin = Liferay.portal2012[instance.get('namespace') + "isAdmin"];
                var upgradeEnabled = Liferay.portal2012[instance.get('namespace') + "upgradeEnabled"];
                var publicTemplates = Liferay.portal2012[instance.get('namespace') + "publicTemplates"];
                var privateTemplates = Liferay.portal2012[instance.get('namespace') + "privateTemplates"];

                var popoverContent = '<div class="popoverContent">';

                popoverContent += '<div id="' + instance.get('namespace') + 'publicTemplates" class="widget-template-group">';
                popoverContent += '<div><span class="widget-template-label">' + instance.t('baseWidgetList.templates.publicTemplates') + '</span></div>';
                popoverContent += '<ul class="widget-template-list">';
                if (publicTemplates && publicTemplates.length > 0) {
                    for (var i = 0; i < publicTemplates.length; i++) {
                        var isCurrentTemplateApplied = instance.get(FIELD_WIDGET_TEMPLATE_ID) === publicTemplates[i].id;
                        popoverContent += instance.createTemplateElement(instance, publicTemplates[i], isCurrentTemplateApplied, false, isAdmin);
                    }

                }
                popoverContent += '</ul>';
                popoverContent += '</div>';

                popoverContent += '<div id="' + instance.get('namespace') + 'privateTemplates"  class="widget-template-group">';
                popoverContent += '<div><span class="widget-template-label">' + instance.t('baseWidgetList.templates.privateTemplates') + '</span></div>';
                popoverContent += '<ul class="widget-template-list">';
                if (privateTemplates && privateTemplates.length > 0) {
                    for (var i = 0; i < privateTemplates.length; i++) {
                        var isCurrentTemplateApplied = instance.get(FIELD_WIDGET_TEMPLATE_ID) === privateTemplates[i].id;
                        popoverContent += instance.createTemplateElement(instance, privateTemplates[i], isCurrentTemplateApplied, upgradeEnabled, isAdmin);
                    }
                }
                popoverContent += '</ul>';
                popoverContent += '</div>';

                popoverContent += '<div class="row widget-template-add">';
                popoverContent += '<div class="col col-md-3"><span class="widget-template-add-label pull-right">' + instance.t('baseWidgetList.templates.new') + '</span></div>';
                popoverContent += '<div class="col col-md-9">' +
                    '<div class="input-group">' +
                    '<input type="text" id="newTemplateName" class="form-control widget-template-name-input" placeholder="' + instance.t('baseWidgetList.templates.saveTemplate') + '">' +
                    '<div class="input-group-append">' +
                    '<button id="saveNewTemplate" class="widget-template-add-button btn btn-primary" type="button"><i class="icon-check"></i></button>' +
                    '</div>' +
                    '</div>' +
                    '</div>';
                popoverContent += '</div>';

                popoverContent += '</div>';

                templateList = new Y.Popover({
                    align: {
                        node: targetElement,
                        points: [Y.WidgetPositionAlign.TC, Y.WidgetPositionAlign.BC]
                    },
                    cssClass: 'widget-template-popup',
                    bodyContent: popoverContent,
                    position: 'bottom'
                }).render();

                var templateListNode = templateList ? templateList.get('srcNode') : undefined;
                if (templateListNode) {
                    templateListNode.get('parentNode').setStyle('z-index', '');
                }
                instance.set('templateList', templateList);


                var saveNewTemplateBtn = Y.one("#saveNewTemplate");
                saveNewTemplateBtn.on('click', function (e) {
                    const isAdmin = Liferay.portal2012[instance.get('namespace') + "isAdmin"];
                    const userId = Liferay.portal2012[instance.get('namespace') + "userId"];
                    var templateNameBox = Y.one('#newTemplateName');
                    var newTemplateName = templateNameBox.get('value');
                    var attrs = {};
                    var allAttributes = instance.getAttrs();
                    var RESERVED_ATTRS = ['host', 'destroyed', 'initialized', 'templateList'];
                    for (var property in allAttributes) {
                        if (allAttributes.hasOwnProperty(property) && !RESERVED_ATTRS.contains(property)) {
                            attrs[property] = instance.get(property);
                        }
                    }
                    let confirmationRequired = false;
                    Y.all('.widget-template-element').each((widgetTemplate) => {
                        let templateNameNode = widgetTemplate.one('.template-name');
                        if (templateNameNode && templateNameNode.html() && templateNameNode.html().trim() === newTemplateName) {
                            if (isAdmin || widgetTemplate.attr('data-user') === userId) {
                                confirmationRequired = true;
                            }
                        }
                    });
                    if (confirmationRequired && !confirm(instance.t('baseWidgetList.templates.confirmOverride'))) {
                        return;
                    }
                    Y.io(Liferay.portal2012[instance.get('namespace') + "saveWidgetTemplateUrl"] + "&templateName=" + newTemplateName, {
                        method: 'POST',
                        data: Y.JSON.stringify(attrs),
                        headers: {
                            'Content-Type': 'application/json'
                        },
                        on: {
                            success: function (id, response) {
                                try {
                                    var createdTemplate = JSON.parse(response.responseText);
                                    if (createdTemplate && createdTemplate.error) {

                                        console.log('error creating template :' + createdTemplate.error);
                                        alert(instance.t('baseWidgetList.templates.saveTemplateError') + ': ' + createdTemplate.error);
                                        return;

                                    }

                                    let existingTemplate = Y.one('#' + 'widgetTemplate_' + createdTemplate.id);
                                    if (existingTemplate) {
                                        existingTemplate.attr('data-user', createdTemplate.user);
                                        let existingTemplateNameNode = existingTemplate.one('.template-name');
                                        if (existingTemplateNameNode) {
                                            existingTemplateNameNode.html(createdTemplate.name);
                                            templateNameBox.set('value', '');
                                            return;
                                        }
                                    }
                                    var publicTemplatesContainer = Y.one('#' + instance.get('namespace') + 'publicTemplates');
                                    if (publicTemplatesContainer) {
                                        publicTemplatesContainer.all('.template-check-control .w-check-template').addClass('hidden');
                                    }

                                    var privatesTemplatesContainer = Y.one('#' + instance.get('namespace') + "privateTemplates");
                                    if (privatesTemplatesContainer) {
                                        privatesTemplatesContainer.all('.template-check-control .w-check-template').addClass('hidden');
                                        var privateTemplateElement = instance.createTemplateElement(instance, createdTemplate, true, upgradeEnabled, isAdmin);
                                        privatesTemplatesContainer.one('ul').append(privateTemplateElement);
                                        attachTemplateEvents(privatesTemplatesContainer.one('ul').one('li:last-child'));
                                    }

                                    templateNameBox.set('value', '');
                                }
                                catch(e){
                                    console.log('error saving template:', e);
                                }

                            },
                            error: function (response) {
                                alert('template save error');
                            }
                        }
                    });
                });

                var attachTemplateEvents = function(templateNode) {
                    templateNode.all(".remove-template").on('click', function (e) {
                        var userConfirmation = confirm(instance.t('baseWidgetList.templates.confirmRemove'));
                        if (userConfirmation) {
                            var templateId = e.target.getAttribute('templateId');
                            var liNode = e.target.ancestor('li');
                            Y.io(Liferay.portal2012[instance.get('namespace') + "deleteWidgetTemplateUrl"] + "&templateId=" + templateId, {
                                method: 'POST',
                                on: {
                                    success: function (response) {
                                        liNode.remove();
                                    },
                                    error: function (response) {
                                        alert('template remove error');
                                    }
                                }
                            });
                        }

                    });
                    templateNode.all(".upgrade-template").on('click', function (e) {
                        var userConfirmation = confirm(instance.t('baseWidgetList.templates.confirmUpgrade'));
                        if (userConfirmation) {
                            var templateId = e.target.getAttribute('templateId');
                            Y.io(Liferay.portal2012[instance.get('namespace') + "upgradeWidgetTemplateUrl"] + "&templateId=" + templateId, {
                                method: 'POST',
                                on: {
                                    success: function (response) {
                                        var removedTemplate = Y.one('#widgetTemplate_' + templateId);
                                        var publicTemplatesDiv = Y.one('#' + instance.get('namespace') + 'publicTemplates ul');
                                        removedTemplate.one('.upgrade-template').remove();
                                        removedTemplate.remove();

                                        if (removedTemplate && publicTemplatesDiv) {
                                            publicTemplatesDiv.appendChild(removedTemplate);
                                        }
                                    },
                                    error: function (response) {
                                        alert(instance.t('baseWidgetList.templates.saveTemplateError'));
                                    }
                                }
                            });
                        }
                    });
                    templateNode.all(".select-template").on('click', function (e) {
                        var userConfirmation = confirm(instance.t('baseWidgetList.templates.confirmApply'));
                        if (userConfirmation) {
                            var templateId = e.target.getAttribute('templateId');
                            Y.all('.w-check-template').each(function (item) {
                                item.addClass('hidden');
                            });
                            var selectedTemplateIcon = Y.one('.w-check-template-' + templateId);
                            if (selectedTemplateIcon) {
                                selectedTemplateIcon.removeClass('hidden');
                            }


                            instance.set(FIELD_WIDGET_TEMPLATE_ID, templateId);
                            Y.io(Liferay.portal2012[instance.get('namespace') + "getWidgetTemplateUrl"] + "&" + instance.get('namespace') + "templateId=" + templateId, {
                                method: 'GET',
                                on: {
                                    success: function (id, response) {
                                        var templateBody = JSON.parse(response.responseText);
                                        instance.refreshElementFromTemplate(instance, templateId, templateBody);

                                    },
                                    error: function (response) {
                                        console.log('template retrieval error');
                                    }
                                }
                            });
                        }
                    });
                };
                Y.all('.widget-template-group .widget-template-list li').each(function (templateNode) {
                    attachTemplateEvents(templateNode);
                });
            }
            else {
                templateList.set('visible', !templateList.get('visible'));
            }
        },
        refreshParticularElementsFromTemplate: function (instance, configuration) {
        },
        refreshElementFromTemplate: function (instance, id, configuration) {
            //clear the current appearenaces
            currentAppearanceOption = '';
            basicAppearance = '';
            currentMetaOtion = '';
            widgetAppearance = [];
            metadataAppearanceList = [];
            metaDataAppearanceObjs = configuration.metadataAppearanceList;
            //instance.initLayoutItem();
            instance.set(FIELD_LAYOUT, configuration.layout);
            instance.set(FIELD_LAYOUT_METADATA, configuration.layoutMetadata);
            instance.set(FIELD_LAYOUT_STYLE, configuration.layoutStyle);

            instance.set(FIELD_ROWS, configuration.layoutRows);
            instance.set(FIELD_COLUMNS, configuration.layoutColumns);
            instance.set(STYLE_PAGINATED, configuration.paginated);
            instance.set(STYLE_SLIDE_SHOW, configuration.slideShow);
            instance.set(FIELD_RESULTS_PAGE, configuration.resultsPage);
            instance.set(FIELD_ORDER_THIS, configuration.showOrderPublicationButton);
            instance.set(FIELD_SHARE_THIS, configuration.showSharePublicationButton);
            instance.set(METADATA_SAVED_OBJS, configuration.selectedMetaDataFieldType);
            if (configuration.slideShowLayout) {
                var slideShowColumns = configuration.slideShowLayout.columns;
                var showControlsDefault = configuration.slideShowLayout.controls;
                var slideNoDefault = configuration.slideShowLayout.slidesNumber;
                var timingDefault = configuration.slideShowLayout.timing;
                var effectsDefault = configuration.slideShowLayout.transition;

            }
            instance.set(FIELD_SLIDE_SHOW_NUMBER_SLIDES, configuration.slideShowNumberSlides);
            instance.set(FIELD_SLIDE_SHOW_TIMING, configuration.slideShowTiming);
            instance.set(FIELD_SELECTED_METADATA, configuration.selectedMetadata);
            instance.set(METADATA_SAVED_OBJS, configuration.selectedMetaDataFieldType);
            instance.set(FIELD_SHOW_ONLY_SELECTED_LANGUAGE_PUBLICATIONS, configuration.showOnlySelectedLanguagePublications);
            instance.set(FIELD_USE_DEFAULT_THUMBNAIL_IMAGE, configuration.useDefaultThumbnailImage);
            instance.set(FIELD_ADVANCED_SET_APPEARANCE, configuration.advancedAppearance);
            instance.set(APPEARANCE_BASIC_DISPLAY, configuration.widgetAppearance);
            instance.set(APPEARANCE_BASIC_DISPLAY_OBJ_LIST, configuration.metadataAppearanceList);
            instance.set(ADVANCED_APPEARANCE_METADATA, configuration.advancedAppearanceMetadata);
            instance.set(ADVANCED_APPEARANCE_PROPERTY, configuration.advancedAppearanceProperty);
            instance.set(FIELD_WIDGET_TEMPLATE_ID, id);
            /*instance.initLayoutItem();
             var layoutOptions = Y.all('.layout-set-select input[type="radio"]');
             if (layoutOptions) {
             for (var layoutIndx = 0; layoutIndx < layoutOptions.size(); layoutIndx++) {
             layoutOptions.item(layoutIndx).set('checked', layoutOptions.item(layoutIndx).get('value') === configuration.layout);
             }
             }*/

            var navTabs = Y.one('.nav-tabs');
            if (navTabs) {
                navTabs.remove();
            }

            var one = Y.one('#tab-1');
            if (one) {
                one.remove();
            }

            var two = Y.one('#tab-2');
            if (two) {
                two.remove();
            }
            var three = Y.one('#tab-3');
            if (three) {
                three.remove();
            }

            var tabPane = Y.one('.tab-pane');
            if (tabPane) {
                tabPane.remove();
            }

            var buttonRows = Y.all('#' + instance.get('namespace') + '_buttonRow');
            if (buttonRows) {
                buttonRows.each(function (item) {
                    item.remove();
                });
            }
            var previewPanel = Y.one('.refresh-panel');
            if (previewPanel) {
                previewPanel.remove();
            }

            instance.initWizard();

            instance.refreshParticularElementsFromTemplate(instance, configuration);
        }
});

Y.BaseWidgetList = BaseWidgetList;

},
'portalop-2014.05.28-17-20', {
    requires: [
        'node',
        'base-build',
        'plugin',
        'classnamemanager',
        'attribute-base',
        'io-base',
        'history-hash',
        'wizardTools',
        'formWidget',
        'paginator',
        'dd-constrain',
        'dd-proxy',
        'dd-drop'
    ]
});
/**
 * This module generates the semantic search widget wizard
 *
 * @module semanticSearchWidgetWizard
 * @requires wizardTools
 * @requires formWidget
 */
YUI.add('semanticSearchWidgetWizard', function(Y) {
    var
            /**
             * Static constant to refer field 'name'
             *
             * @property FIELD_TITLE
             * @type String
             * @static
             * @final
             */
            FIELD_NAME = 'name',
            FIELD_DESCRIPTION = 'description'

    /**
     * Generates the dom and dom events for semantic search widget wizard
     *
     * @param cfg
     * @constructor
     * @class SemanticSearchWidgetWizard
     * @extends AbstractWizard
     */
    function SemanticSearchWidgetWizard(cfg){
        SemanticSearchWidgetWizard.superclass.constructor.apply(this, arguments);
    }

    SemanticSearchWidgetWizard.NAME = 'SemanticSearchWidgetWizard';
    SemanticSearchWidgetWizard.NS = 'SemanticSearchWidgetWizard';

    SemanticSearchWidgetWizard.ATTRS = {
        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value:''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value:''
        }
    };
    Y.extend(SemanticSearchWidgetWizard, Y.AbstractWizard, {
        initWizard : function(){
            var instance = this,
                host = this.get('host'),
                isEdit = instance.get('widgetId') > 0;
            instance.set('widgetType', '4');

            new Y.PanelElement({
                children: [
                    new Y.InputElement({
                        label: instance.t('searchBox.name'),
                        name: FIELD_NAME,
                        modelInstance: instance,
                        placeholder:instance.t('baseWidgetList.name.placeholder'),
                        cssClass:'widget-input',
                        required: true,
                        validateFunction: function () {
                            instance.validateWidget();
                        }
                    }),
                    new Y.InputElement({
                        label: instance.t('searchBox.description'),
                        name: FIELD_DESCRIPTION,
                        placeholder: instance.t('baseWidgetList.description.placeholder'),
                        modelInstance: instance,
                        cssClass:'widget-input'
                    }),
                    instance.getLanguageSelector(),
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + "_buttonRow",
                        children: [
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!instance.get('widgetId') > 0 ? ' disabled' : ''),
                                htmlContent: instance.t('searchBox.save'),
                                onClick: function (e) {
                                    if (!instance.validateWidget()) {
                                        return;
                                    }
                                    instance.doSaveWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right get-button' + (!instance.get('widgetId') > 0 ? ' hidden' : ''),
                                htmlContent: instance.t('searchBox.getCode'),
                                onClick: function (e) {
                                    instance.doGetWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!instance.get('widgetId') > 0 ? ' hidden' : ''),
                                htmlContent: instance.t('baseWidgetList.cancel'),
                                onClick: function (e) {
                                    instance.doReturnToMyWidgets();
                                }
                            })
                        ]
                    })
                ]
            }).render(host);

            instance.attachPreviewPanel(host, function() {
                instance.doPreviewWidget();
            },function(){
                instance.clearCache();
            });
            instance.displayPreviewNode();
        },

        validateWidget: function() {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function() {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });

            if (isValidated) {
                actionButtons.removeClass('disabled');
            } else {
                actionButtons.addClass('disabled');
            }
            return isValidated;
        }

    });

    Y.namespace('Plugin').SemanticSearchWidgetWizard = SemanticSearchWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires:
            [
                'node',
                'base-build',
                'plugin',
                'classnamemanager',
                'attribute-base',
                'io-base',
                'history-hash',
                'wizardTools',
                'formWidget'
            ]
});
/**
 * This module generates the public procurement search results widget
 *
 * @module publicProcurementSearchResultsWidgetWizard
 * @requires baseWidgetList
 */
YUI.add('publicProcurementSearchResultsWidgetWizard', function (Y) {

    var
            /**
             * Static constant to refer field 'title'
             *
             * @property FIELD_TITLE
             * @type String
             * @static
             * @final
             */
            FIELD_NAME = 'name',
            FIELD_DESCRIPTION = 'description',
            FIELD_TARGET_PAGE = 'targetPage',
            FIELD_EXCLUDE = 'excludedPermalinks',
            FIELD_SELECTED_METADATA = 'selectedMetadata',
            FIELD_ADVANCED_SET_APPEARANCE = 'advancedAppearance',
            FIELD_LAYOUT = 'layout',

            APPEARANCE_BASIC_DISPLAY = 'widgetAppearance',
            APPEARANCE_BASIC_DISPLAY_OBJ_LIST = 'metadataAppearanceList',

            /**
             *  Object used to set the MetaTags field types.
             *  Do not modify, MetaTags types are predefined.
             * @type {{TEXT: string, ICON: string, IMAGE: string}}
             * @static
             * @final
             */

            FIELDTYPE = {TEXT: 'TEXT', ICON: 'ICON', IMAGE: 'IMAGE'},


            /**
             * Object used in string replacement on function calls.
             * Can be extended in future with other attributes.
             * @type {{CHECKBOX: string, INPUT: string, RADIO: string}}
             * @static
             * @final
             */

            ELEMENT_TYPE = {
                CHECKBOX: 'CheckboxElement',
                INPUT: 'InputElement',
                RADIO: 'RadioElement'
            },

            /**
             * Object used to set status of elements.
             * Can be extended in the future.
             * @type {{CHECKBOX_STATUS: string, VALUE: string, NAMESPACE: string}}
             * @static
             * @final
             */
            ELEM_ATTR = {
                CHECKBOX_STATUS: 'checked',
                VALUE: 'value',
                NAMESPACE: 'namespace'
            },

            /**
             * Array of MetaData option objects.
             * Do not populate by default.
             * @type {Array}
             */
            METADATA_SELECTION_OBJS = [],


            metadataAppearanceList = [],

            slideShowLayout = {},

        METADATA = [{
            value: 'Title',
            key: 'title',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Description',
            key: 'description',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Published',
            key: 'published_date',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Submission deadline',
            key: 'submission_deadline',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Status',
            key: 'status',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Type of contract',
            key: 'type_of_contract',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Buyer',
            key: 'buyer',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Estimated contract value',
            key: 'estimated_contract_value',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Main CPV Code',
            key: 'main_cpv',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Place of performance (NUTS)',
            key: 'nuts',
            type: FIELDTYPE.TEXT
        }],

            /**
             * Static constant to refer field 'source'
             *
             * @property FIELD_SOURCE
             * @type String
             * @static
             * @final
             */
            FIELD_SOURCE = 'source',

            /**
             * Static constant to refer field 'header'
             *
             * @property FIELD_HEADER
             * @type String
             * @static
             * @final
             */
            FIELD_HEADER = 'header',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_FOOTER
             * @type String
             * @static
             * @final
             */
            FIELD_FOOTER = 'footer',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_SAVED_SEARCH
             * @type {string}
             * @static
             * @final
             */
            FIELD_SAVED_SEARCH = 'savedSearch',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_SPARQL_QUERY
             * @type {string}
             * @static
             * @final
             */
            FIELD_SPARQL_QUERY = 'sparql',


            SEARCH_SOURCE_ELEMENT;


    /**
     * Generates the dom and dom events for search result widget wizard
     *
     * @param cfg
     * @constructor
     * @class PublicProcurementSearchResultsWidgetWizard
     * @extends BaseWidgetList
     */
    function PublicProcurementSearchResultsWidgetWizard(cfg) {
        PublicProcurementSearchResultsWidgetWizard.superclass.constructor.apply(this, arguments);
        this.initSavedObjects(cfg);
    }

    PublicProcurementSearchResultsWidgetWizard.NAME = 'PublicProcurementSearchResultsWidgetWizard';
    PublicProcurementSearchResultsWidgetWizard.NS = 'PublicProcurementSearchResultsWidgetWizard';

    PublicProcurementSearchResultsWidgetWizard.ATTRS = {
        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },

        /**
         * Keeps the source for the results. Can be one of 'widget' or 'source'.
         * If the source is 'widget', then the query will be taken from the parent URL and be passed to the server to display the results.
         *
         * @attribute source
         * @type {String}
         * @default ''
         */
        source: {
            value: " "
        },

        setAppearanceTabs: null,

        /**
         * A list of header options to be displayed in the widget
         * See {{#crossLink 'PublicProcurementSearchResultsWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute header
         * @type {Array}
         * @default []
         */
        header: {
            value: [
                "nrOfResults",
                "navigation"
            ]
        },

        /**
         * A list of footer options to be displayed in the widget
         * See {{#crossLink 'PublicProcurementSearchResultsWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute footer
         * @type {Array}
         * @default []
         */
        footer: {
            value: [
                "nrOfResults",
                "navigation"
            ]
        },

        /**
         * Keeps the selected search widget
         *
         * @attribute searchWidget
         * @type {String}
         * @deprecated
         */
        searchWidget: {
            value: ""
        },

        /**
         * Keeps the selected saved search id
         *
         * @attribute savedSearch
         * @type {String}
         */
        savedSearch: {
            value: ''
        },

        excludedPermalinks: {
            value: ''
        },

        /**
         * Keeps the sparql query to be executed
         *
         * @attribute savedSearch
         * @type {String}
         * @deprecated
         */
        sparql: {
            value: ''
        },
        /**
         *  metadata selection refactoring
         *  array of objects containing selected metadata
         *  each obect has following propertes
         *  key - code of metadata attribute
         *  metadataFieldType - type of metadata attribute
         *  showLabel - value of showLabel checkbox
         *  maxLength - number of characters to be displayed
         *  formatsType - for formats metadata specify if they will be displayed as ICON or TEXT
         *
         * @type {Array}
         */
        selectedMetaDataFieldType: {
            value: [
                {
                    "key": "title",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": false
                },
                {
                    "key": "description",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": false
                },
                {
                    "key": "published_date",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "submission_deadline",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "status",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "buyer",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "main_cpv",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                }
            ]
        },

        selectedMetadata: {
            value: [
                "title",
                "description",
                "published_date",
                "submission_deadline",
                "status",
                "type_of_contract",
                "buyer",
                "estimated_contract_value",
                "main_cpv",
                "nuts"
            ]
        },

        layoutRows: {
            value: 5
        },

        metadataAppearanceList: {
            value: []
        },

        widgetAppearance: {
        },

        slideShowLayout: {
            value: {}
        },

        /**
         * A list of result formats options to be displayed in the widget
         * See {{#crossLink 'PublicProcurementSearchResultsWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute result formats
         * @type {Array}
         * @default []
         */
        resultFormats: {
            value: []
        }

    };

    Y.extend(PublicProcurementSearchResultsWidgetWizard, Y.BaseWidgetList, {
        /**
         * Initialization of the inner tabs.
         */
        initWizard: function () {
            var instance = this,
                    host = this.get('host');

            //add button for templates
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general'),
                    instance.t('searchResult.appearance'),
                    instance.t('statistics.search.results')
                ],
                children: [
                    instance.getGeneralSettings(),
                    instance.getAppearanceSettings(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                        if(instance.get('layoutColumns') && instance.get('layoutRows')) {
                            if ((instance.get('layoutColumns') * instance.get('layoutRows')) > 50 &&
                                Y.one(".message-to-show").hasClass('hidden')) {
                                Y.one(".message-to-show").removeClass('hidden');
                            } else {
                                Y.one(".message-to-show").addClass('hidden');
                            }
                        }
                        instance.validateWidget();
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();
            instance.initLayoutItem();

            /**
             * Button bar present at footer for all tabs.
             */

            new Y.HtmlElement({
                cssClass: '',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + '_buttonRow',
                        children: instance.getButtonsBar()
                    })
                ]
            }).render(host);

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.convertLayoutStyleToJson();
                instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });

            instance.fireLoadCallFinished();
        },

        /**
         * First tab creation.
         * @returns {Y.PanelElement}
         */

        getGeneralSettings: function () {
            var instance = this, tab;
            var metadataOpt = instance.getMetadataTranslation();

            tab = new Y.HtmlElement({
                id: 'tab-1',
                cssClass: 'tab-pane active',
                children: [
                    new Y.PanelElement({
                        label: instance.t('publication.properties'),
                        children: [
                            new Y.InputElement({
                                label: instance.t('searchResult.name'),
                                name: FIELD_NAME,
                                modelInstance: instance,
                                placeholder: instance.t('baseWidgetList.name.placeholder'),
                                cssClass: 'widget-input',
                                required: true,
                                validateFunction: function () {
                                    instance.validateWidget();
                                }
                            }),
                            new Y.InputElement({
                                label: instance.t('searchResult.description'),
                                name: FIELD_DESCRIPTION,
                                placeholder: instance.t('baseWidgetList.description.placeholder'),
                                modelInstance: instance,
                                cssClass: 'widget-input'
                            }),

                            /**
                             * Language selection option. Automatic option or manual selection of language
                             */
                            instance.getLanguageSelector()
                        ]
                    }),
                    new Y.PanelElement({
                        label: instance.t('searchResult.source'),
                        children: [
                            SEARCH_SOURCE_ELEMENT = new Y.SearchSourceElement({
                                labels: {
                                    radioSearchWidget: instance.t('searchResult.searchWidget'),
                                    radioAvailableSearches: instance.t('searchResult.savedSearch'),
                                    tableHeader_no: instance.t('searchResult.table.no'),
                                    tableHeader_searchName: instance.t('searchResult.table.searchName'),
                                    tableHeader_searchType: instance.t('searchResult.table.searchType'),
                                    exclude: instance.t('searchResult.exclude'),
                                    excludeDescription: instance.t('searchResult.exclude.observation'),
                                    searchType_simple: instance.t('searchResult.searchType.simple'),
                                    searchType_elif: instance.t('searchResult.searchType.elif'),
                                    searchType_advanced: instance.t('searchResult.searchType.advanced'),
                                    searchType_browseBySubject: instance.t('searchResult.searchType.browseBySubject'),
                                    searchType_sparql: instance.t('searchResult.searchType.sparql')
                                },
                                modelInstance: instance,
                                fieldSource: FIELD_SOURCE,
                                fieldSavedSearch: FIELD_SAVED_SEARCH,
                                fieldExcluded: FIELD_EXCLUDE,
                                getSavedSearchesURL: Liferay.portal2012[instance.get('namespace') + "myPublicProcurementSearchesUrl"],
                                mySearchesPageURL: Liferay.portal2012[instance.get('namespace') + "mySearchesPageURL"]
                            })
                        ]
                    }),

                    /**
                     * Metadata selection, default metadata.
                     */
                    new Y.HtmlElement({
                        id: instance.get(ELEM_ATTR.NAMESPACE) + "metaselect",
                        wrapperCssClass: 'row',
                        children: [
                            new Y.MetadataEditInTableElement({
                                label: instance.t('baseWidgetList.displayedMetadata'),
                                modelInstance: instance,
                                name: FIELD_SELECTED_METADATA,
                                options: METADATA,
                                displayOrderButton: false
                            })]
                    }),
                    instance.getTargetPageStep()
                ]
            });

            return tab;
        },

        /**
         * This function will return the object tab in order to display the appearance configuration options.
         * The appearance options are initialized if there is any configuration, or an widget is edited.
         * @returns {Y.PanelElement}
         */
        getAppearanceSettings: function () {
            var instance = this,
                    tab;

            var layout = instance.getLayoutStep();


            var basicConfiguration = null;
            var advancedConfiguration = null;

            /**
             * Basic config for simple Appearance
             */
            if (instance.get('widgetAppearance') != undefined && instance.get('widgetAppearance') != null) {
                basicConfiguration = instance.get('widgetAppearance');
            }

            /**
             * advanced config for simple Appearance
             */
            if (instance.get('metadataAppearanceList') != undefined && instance.get('metadataAppearanceList') != null) {
                advancedConfiguration = instance.get('metadataAppearanceList');
            }


            /**
             * Slide show edit configuration
             */
            if (instance.get('slideShowLayout') != undefined && instance.get('slideShowLayout') != null) {
                slideShowLayout = instance.getLayoutStyleStep(instance.get('slideShowLayout'));
            }
            else {
                slideShowLayout = instance.getLayoutStyleStep(null);
            }

            /**
             * Appearance settings tab configuration.             *
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(basicConfiguration, advancedConfiguration, true, true);


            instance.after(FIELD_LAYOUT + "Change", function (e) {
                var instance = e.currentTarget;
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance._addDropDownEvents();
            instance._layoutSet(true);

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline',
                        children: instance.getHeaderFooterOptionList(FIELD_HEADER)
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline',
                        children: instance.getHeaderFooterOptionList(FIELD_FOOTER)
                    }),
                    layout,
                    slideShowLayout,
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });

            return tab;
        },

        getStatisticsTable: function () {
            var instance = this, tab;
            var isEdit = instance.get('widgetId') > 0;

            var tableStatistics = [];

            tableStatistics.push(instance.getTableStatistics());

            if (isEdit) {
                tableStatistics.push(instance.getTableDetaliedStatistics());
            }

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: tableStatistics
                    }),
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        // label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        htmlContent: '<a  class="pull-right" href="' + Liferay.portal2012[instance.get('namespace') + "downloadStatisticsSearchResults"] + '">' + instance.t('statistics.download') + '</a>'
                    })
                ]
            });

            return tab;
        },

        getTableStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSearchResults"],
                    data = [],
                    columns = [],
                    i,
                    len;
            var widgetElement;
            var isEdit = instance.get('widgetId') > 0;


            if (widgetList) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: parseInt(widgetElement.visits),
                        clicks: parseInt(widgetElement.clicksPerm + widgetElement.clicksSearch)
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            if (!isEdit) {
                table.set('rowsPerPage', 25);
                table.set('pageSizes', [10, 25, 50])
                table.set('paginatorLocation', ['footer']);
            }

            return table;
        },

        getTableDetaliedStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSearchResults"],
                    data = [],
                    columns = [],
                    i, j,
                    len, lenJ;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement, detailsWidgetElement = [];


            if (widgetList) {
                for (i = 0, len = (widgetList.length - 1); i < len; i++) {
                    if (widgetList[i].publicationStatisticsDTOList) {
                        detailsWidgetElement = widgetList[i].publicationStatisticsDTOList;

                        for (j = 0, lenJ = detailsWidgetElement.length; j < lenJ; j++) {
                            widgetElement = detailsWidgetElement[j];
                            data.push({
                                publications: widgetElement.publication,
                                searchClicks: widgetElement.searchClicks,
                                noImpresions: widgetElement.noImpressions

                            });
                        }
                    }
                }
            }

            columns = [
                {
                    key: 'publications',
                    label: instance.t('statistics.table.publications'),
                    width: '60%',
                    className: 'numeric'
                },
                {
                    key: 'noImpresions',
                    width: '20%',
                    label: instance.t('statistics.table.impressions'),
                    sortable: true
                },
                {
                    key: 'searchClicks',
                    width: '20%',
                    label: instance.t('statistics.table.clicks'),
                    sortable: true
                }

            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 25);
            table.set('pageSizes', [10, 25, 50])
            table.set('paginatorLocation', ['footer']);


            return table;
        },

        /**
         * Not implemented, this was only a proposal.
         * @returns {Y.PanelElement}
         */
        getStatistics: function () {
            var instance = this,
                    tab;

//            tab = new Y.PanelElement({
//                wrapperCssClass: 'step step-2 hide',
//                children: []
//            });

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        children: instance.getButtonsBar()
                    })
                ]
            });

            return tab;
        },

        /**
         * Returns the button bar for the widget.
         * @returns {Array}
         */
        getButtonsBar: function () {
            var instance = this, toolBar = [];
            var isExistentWidget = (parseInt(instance.get('widgetId')) > 0);
            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' disabled' : ''),
                htmlContent: instance.t('baseWidgetList.save'),
                onClick: function (e) {
                    if (!instance.validateWidget()) {
                        return;
                    }
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertLayoutStyleToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doSaveWidget();
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right get-button' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.getCode'),
                onClick: function (e) {
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertLayoutStyleToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doGetWidget()
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.cancel'),
                onClick: function (e) {
                    instance.doReturnToMyWidgets();
                }
            }));

            return toolBar;
        },


        getBasicAppearence: function () {
            var instance = this;
            var element;

            element = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-inner-1',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline'
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline'
                    })
                ]
            });

            return element;

        },


        getAdvancedAppearence: function () {
            var instance = this;
            var element;

            element = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-inner-2',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline'
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline'
                    })
                ]
            });

            return element;

        },

        setWizardType: function () {
            var instance = this;
            instance.set("widgetType", 8);
        },
        setLoadCalls: function () {
            var instance = this;
            instance.set("loadCalls", 1);
        },

        validateWidget: function () {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });

            if(instance.get('layoutColumns') && instance.get('layoutRows') && isValidated) {
                if ((instance.get('layoutColumns') * instance.get('layoutRows')) > 50) {
                    isValidated = false;
                }
            }

            if (isValidated) {
                actionButtons.removeClass('disabled');
                actionButtons.set('disabled',false)
            }
            else {
                actionButtons.addClass('disabled');
                actionButtons.set('disabled',true)
            }
            return isValidated;
        },

        metadataSelected: function (metadataArray, value) {
            if (metadataArray) {
                var arraySize = metadataArray.length;
                for (var i = 0; i < arraySize; i++) {
                    if (metadataArray[i] === value) {
                        return true;
                    }
                }
            }
            return false;
        }
    });

    Y.namespace('Plugin').PublicProcurementSearchResultsWidgetWizard = PublicProcurementSearchResultsWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'baseWidgetList',
        'aui-tabview',
        'tabview'
    ]
});
/**
 * This module generates the publication view widget wizard
 *
 * @module searchResultWidgetWizard
 * @requires baseWidgetList
 */
YUI.add('searchResultWidgetWizard', function (Y) {

    var
            /**
             * Static constant to refer field 'title'
             *
             * @property FIELD_TITLE
             * @type String
             * @static
             * @final
             */
            FIELD_NAME = 'name',
            FIELD_DESCRIPTION = 'description',
            FIELD_TARGET_PAGE = 'targetPage',
            FIELD_EXCLUDE = 'excludedPermalinks',
            FIELD_SELECTED_METADATA = 'selectedMetadata',
            FIELD_ADVANCED_SET_APPEARANCE = 'advancedAppearance',
            FIELD_LAYOUT = 'layout',

            APPEARANCE_BASIC_DISPLAY = 'widgetAppearance',
            APPEARANCE_BASIC_DISPLAY_OBJ_LIST = 'metadataAppearanceList',

            /**
             *  Object used to set the MetaTags field types.
             *  Do not modify, MetaTags types are predefined.
             * @type {{TEXT: string, ICON: string, IMAGE: string}}
             * @static
             * @final
             */

            FIELDTYPE = {TEXT: 'TEXT', ICON: 'ICON', IMAGE: 'IMAGE'},


            /**
             * Object used in string replacement on function calls.
             * Can be extended in future with other attributes.
             * @type {{CHECKBOX: string, INPUT: string, RADIO: string}}
             * @static
             * @final
             */

            ELEMENT_TYPE = {
                CHECKBOX: 'CheckboxElement',
                INPUT: 'InputElement',
                RADIO: 'RadioElement'
            },

            /**
             * Object used to set status of elements.
             * Can be extended in the future.
             * @type {{CHECKBOX_STATUS: string, VALUE: string, NAMESPACE: string}}
             * @static
             * @final
             */
            ELEM_ATTR = {
                CHECKBOX_STATUS: 'checked',
                VALUE: 'value',
                NAMESPACE: 'namespace'
            },

            /**
             * Array of MetaData option objects.
             * Do not populate by default.
             * @type {Array}
             */
            METADATA_SELECTION_OBJS = [],


            metadataAppearanceList = [],

            slideShowLayout = {},

            METADATA = [{
                value: 'Title',
                key: 'title',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Subtitle',
                key: 'subtitle',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Abstract',
                key: 'abstract',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Date',
                key: 'publishing_date',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Author',
                key: 'authors',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Subject',
                key: 'subjects',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Format',
                key: 'available_formats',
                type: FIELDTYPE.ICON
            }, {
                value: 'Thumbnail',
                key: 'thumbnail',
                type: FIELDTYPE.IMAGE
            }],

            /**
             * Static constant to refer field 'source'
             *
             * @property FIELD_SOURCE
             * @type String
             * @static
             * @final
             */
            FIELD_SOURCE = 'source',

            /**
             * Static constant to refer field 'header'
             *
             * @property FIELD_HEADER
             * @type String
             * @static
             * @final
             */
            FIELD_HEADER = 'header',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_FOOTER
             * @type String
             * @static
             * @final
             */
            FIELD_FOOTER = 'footer',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_SAVED_SEARCH
             * @type {string}
             * @static
             * @final
             */
            FIELD_SAVED_SEARCH = 'savedSearch',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_SPARQL_QUERY
             * @type {string}
             * @static
             * @final
             */
            FIELD_SPARQL_QUERY = 'sparql',


            SEARCH_SOURCE_ELEMENT;


    /**
     * Generates the dom and dom events for search result widget wizard
     *
     * @param cfg
     * @constructor
     * @class SearchResultWidgetWizard
     * @extends BaseWidgetList
     */
    function SearchResultWidgetWizard(cfg) {
        SearchResultWidgetWizard.superclass.constructor.apply(this, arguments);
        this.initSavedObjects(cfg);
    }

    SearchResultWidgetWizard.NAME = 'SearchResultWidgetWizard';
    SearchResultWidgetWizard.NS = 'SearchResultWidgetWizard';

    SearchResultWidgetWizard.ATTRS = {
        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },

        /**
         * Keeps the source for the results. Can be one of 'widget' or 'source'.
         * If the source is 'widget', then the query will be taken from the parent URL and be passed to the server to display the results.
         *
         * @attribute source
         * @type {String}
         * @default ''
         */
        source: {
            value: " "
        },

        setAppearanceTabs: null,

        /**
         * A list of header options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute header
         * @type {Array}
         * @default []
         */
        header: {
            value: []
        },

        /**
         * A list of footer options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute footer
         * @type {Array}
         * @default []
         */
        footer: {
            value: []
        },

        /**
         * Keeps the selected search widget
         *
         * @attribute searchWidget
         * @type {String}
         * @deprecated
         */
        searchWidget: {
            value: ""
        },

        /**
         * Keeps the selected saved search id
         *
         * @attribute savedSearch
         * @type {String}
         */
        savedSearch: {
            value: ''
        },

        excludedPermalinks: {
            value: ''
        },

        /**
         * Keeps the sparql query to be executed
         *
         * @attribute savedSearch
         * @type {String}
         * @deprecated
         */
        sparql: {
            value: ''
        },
        /**
         *  metadata selection refactoring
         *  array of objects containing selected metadata
         *  each obect has following propertes
         *  key - code of metadata attribute
         *  metadataFieldType - type of metadata attribute
         *  showLabel - value of showLabel checkbox
         *  maxLength - number of characters to be displayed
         *  formatsType - for formats metadata specify if they will be displayed as ICON or TEXT
         *
         * @type {Array}
         */
        selectedMetaDataFieldType: {
            value: []
        },

        metadataAppearanceList: {
            value: []
        },

        widgetAppearance: {
            value: {}
        },

        slideShowLayout: {
            value: {}
        },

        /**
         * A list of result formats options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute result formats
         * @type {Array}
         * @default []
         */
        resultFormats: {
            value: []
        }

    };

    Y.extend(SearchResultWidgetWizard, Y.BaseWidgetList, {
        /**
         * Initialization of the inner tabs.
         */
        initWizard: function () {
            var instance = this,
                    host = this.get('host');

            //add button for templates
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general'),
                    instance.t('searchResult.appearance'),
                    instance.t('statistics.search.results')
                ],
                children: [
                    instance.getGeneralSettings(),
                    instance.getAppearanceSettings(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                        if(instance.get('layoutColumns') && instance.get('layoutRows')) {
                            if ((instance.get('layoutColumns') * instance.get('layoutRows')) > 50 &&
                                Y.one(".message-to-show").hasClass('hidden')) {
                                Y.one(".message-to-show").removeClass('hidden');
                            } else {
                                Y.one(".message-to-show").addClass('hidden');
                            }
                        }
                        instance.validateWidget();
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();
            instance.initLayoutItem();

            /**
             * Button bar present at footer for all tabs.
             */

            new Y.HtmlElement({
                cssClass: '',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + '_buttonRow',
                        children: instance.getButtonsBar()
                    })
                ]
            }).render(host);

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.convertLayoutStyleToJson();
                instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });

            instance.fireLoadCallFinished();
        },

        /**
         * First tab creation.
         * @returns {Y.PanelElement}
         */

        getGeneralSettings: function () {
            var instance = this, tab;
            var metadataOpt = instance.getMetadataTranslation();

            tab = new Y.HtmlElement({
                id: 'tab-1',
                cssClass: 'tab-pane active',
                children: [
                    new Y.PanelElement({
                        label: instance.t('publication.properties'),
                        children: [
                            new Y.InputElement({
                                label: instance.t('searchResult.name'),
                                name: FIELD_NAME,
                                modelInstance: instance,
                                placeholder: instance.t('baseWidgetList.name.placeholder'),
                                cssClass: 'widget-input',
                                required: true,
                                validateFunction: function () {
                                    instance.validateWidget();
                                }
                            }),
                            new Y.InputElement({
                                label: instance.t('searchResult.description'),
                                name: FIELD_DESCRIPTION,
                                placeholder: instance.t('baseWidgetList.description.placeholder'),
                                modelInstance: instance,
                                cssClass: 'widget-input'
                            }),

                            /**
                             * Language selection option. Automatic option or manual selection of language
                             */
                            instance.getLanguageSelector()
                        ]
                    }),
                    new Y.PanelElement({
                        label: instance.t('searchResult.source'),
                        children: [
                            SEARCH_SOURCE_ELEMENT = new Y.SearchSourceElement({
                                labels: {
                                    radioSearchWidget: instance.t('searchResult.searchWidget'),
                                    radioAvailableSearches: instance.t('searchResult.savedSearch'),
                                    tableHeader_no: instance.t('searchResult.table.no'),
                                    tableHeader_searchName: instance.t('searchResult.table.searchName'),
                                    tableHeader_searchType: instance.t('searchResult.table.searchType'),
                                    exclude: instance.t('searchResult.exclude'),
                                    excludeDescription: instance.t('searchResult.exclude.observation'),
                                    searchType_simple: instance.t('searchResult.searchType.simple'),
                                    searchType_elif: instance.t('searchResult.searchType.elif'),
                                    searchType_advanced: instance.t('searchResult.searchType.advanced'),
                                    searchType_browseBySubject: instance.t('searchResult.searchType.browseBySubject'),
                                    searchType_sparql: instance.t('searchResult.searchType.sparql')
                                },
                                modelInstance: instance,
                                fieldSource: FIELD_SOURCE,
                                fieldSavedSearch: FIELD_SAVED_SEARCH,
                                fieldExcluded: FIELD_EXCLUDE,
                                getSavedSearchesURL: Liferay.portal2012[instance.get('namespace') + "mySearchesUrl"],
                                mySearchesPageURL: Liferay.portal2012[instance.get('namespace') + "mySearchesPageURL"]
                            })
                        ]
                    }),

                    /**
                     * Metadata selection, default metadata.
                     */
                    new Y.HtmlElement({
                        id: instance.get(ELEM_ATTR.NAMESPACE) + "metaselect",
                        wrapperCssClass: 'row',
                        children: [
                            new Y.MetadataEditInTableElement({
                                label: instance.t('baseWidgetList.displayedMetadata'),
                                modelInstance: instance,
                                name: FIELD_SELECTED_METADATA,
                                options: METADATA,
                                displayOrderButton: true
                            })]
                    }),
                    instance.getTargetPageStep()
                ]
            });

            return tab;
        },

        /**
         * This function will return the object tab in order to display the appearance configuration options.
         * The appearance options are initialized if there is any configuration, or an widget is edited.
         * @returns {Y.PanelElement}
         */
        getAppearanceSettings: function () {
            var instance = this,
                    tab;

            var layout = instance.getLayoutStep();


            var basicConfiguration = null;
            var advancedConfiguration = null;

            /**
             * Basic config for simple Appearance
             */
            if (instance.get('widgetAppearance') != undefined && instance.get('widgetAppearance') != null) {
                basicConfiguration = instance.get('widgetAppearance');
            }

            /**
             * advanced config for simple Appearance
             */
            if (instance.get('metadataAppearanceList') != undefined && instance.get('metadataAppearanceList') != null) {
                advancedConfiguration = instance.get('metadataAppearanceList');
            }


            /**
             * Slide show edit configuration
             */
            if (instance.get('slideShowLayout') != undefined && instance.get('slideShowLayout') != null) {
                slideShowLayout = instance.getLayoutStyleStep(instance.get('slideShowLayout'));
            }
            else {
                slideShowLayout = instance.getLayoutStyleStep(null);
            }

            /**
             * Appearance settings tab configuration.             *
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(basicConfiguration, advancedConfiguration, true, true);


            instance.after(FIELD_LAYOUT + "Change", function (e) {
                var instance = e.currentTarget;
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance._addDropDownEvents();
            instance._layoutSet(true);

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline',
                        children: instance.getHeaderFooterOptionList(FIELD_HEADER)
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline',
                        children: instance.getHeaderFooterOptionList(FIELD_FOOTER)
                    }),
                    layout,
                    slideShowLayout,
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });

            return tab;
        },

        getStatisticsTable: function () {
            var instance = this, tab;
            var isEdit = instance.get('widgetId') > 0;

            var tableStatistics = [];

            tableStatistics.push(instance.getTableStatistics());

            if (isEdit) {
                tableStatistics.push(instance.getTableDetaliedStatistics());
            }

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: tableStatistics
                    }),
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        // label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        htmlContent: '<a  class="pull-right" href="' + Liferay.portal2012[instance.get('namespace') + "downloadStatisticsSearchResults"] + '">' + instance.t('statistics.download') + '</a>'
                    })
                ]
            });

            return tab;
        },

        getTableStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSearchResults"],
                    data = [],
                    columns = [],
                    i,
                    len;
            var widgetElement;
            var isEdit = instance.get('widgetId') > 0;


            if (widgetList) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: parseInt(widgetElement.visits),
                        clicks: parseInt(widgetElement.clicksPerm + widgetElement.clicksSearch)
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            if (!isEdit) {
                table.set('rowsPerPage', 25);
                table.set('pageSizes', [10, 25, 50])
                table.set('paginatorLocation', ['footer']);
            }

            return table;
        },

        getTableDetaliedStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSearchResults"],
                    data = [],
                    columns = [],
                    i, j,
                    len, lenJ;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement, detailsWidgetElement = [];


            if (widgetList) {
                for (i = 0, len = (widgetList.length - 1); i < len; i++) {
                    if (widgetList[i].publicationStatisticsDTOList) {
                        detailsWidgetElement = widgetList[i].publicationStatisticsDTOList;

                        for (j = 0, lenJ = detailsWidgetElement.length; j < lenJ; j++) {
                            widgetElement = detailsWidgetElement[j];
                            data.push({
                                publications: widgetElement.publication,
                                searchClicks: widgetElement.searchClicks,
                                noImpresions: widgetElement.noImpressions

                            });
                        }
                    }
                }
            }

            columns = [
                {
                    key: 'publications',
                    label: instance.t('statistics.table.publications'),
                    width: '60%',
                    className: 'numeric'
                },
                {
                    key: 'noImpresions',
                    width: '20%',
                    label: instance.t('statistics.table.impressions'),
                    sortable: true
                },
                {
                    key: 'searchClicks',
                    width: '20%',
                    label: instance.t('statistics.table.clicks'),
                    sortable: true
                }

            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 25);
            table.set('pageSizes', [10, 25, 50])
            table.set('paginatorLocation', ['footer']);


            return table;
        },

        /**
         * Not implemented, this was only a proposal.
         * @returns {Y.PanelElement}
         */
        getStatistics: function () {
            var instance = this,
                    tab;

//            tab = new Y.PanelElement({
//                wrapperCssClass: 'step step-2 hide',
//                children: []
//            });

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        children: instance.getButtonsBar()
                    })
                ]
            });

            return tab;
        },

        /**
         * Returns the button bar for the widget.
         * @returns {Array}
         */
        getButtonsBar: function () {
            var instance = this, toolBar = [];
            var isExistentWidget = (parseInt(instance.get('widgetId')) > 0);
            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' disabled' : ''),
                htmlContent: instance.t('baseWidgetList.save'),
                onClick: function (e) {
                    if (!instance.validateWidget()) {
                        return;
                    }
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertLayoutStyleToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doSaveWidget();
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right get-button' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.getCode'),
                onClick: function (e) {
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertLayoutStyleToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doGetWidget()
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.cancel'),
                onClick: function (e) {
                    instance.doReturnToMyWidgets();
                }
            }));

            return toolBar;
        },


        getBasicAppearence: function () {
            var instance = this;
            var element;

            element = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-inner-1',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline'
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline'
                    })
                ]
            });

            return element;

        },


        getAdvancedAppearence: function () {
            var instance = this;
            var element;

            element = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-inner-2',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline'
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline'
                    })
                ]
            });

            return element;

        },

        setWizardType: function () {
            var instance = this;
            instance.set("widgetType", 2);
        },
        setLoadCalls: function () {
            var instance = this;
            instance.set("loadCalls", 1);
        },

        validateWidget: function () {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });

            if(instance.get('layoutColumns') && instance.get('layoutRows') && isValidated) {
                if ((instance.get('layoutColumns') * instance.get('layoutRows')) > 50) {
                    isValidated = false;
                }
            }

            if (isValidated) {
                actionButtons.removeClass('disabled');
                actionButtons.set('disabled',false)
            }
            else {
                actionButtons.addClass('disabled');
                actionButtons.set('disabled',true)
            }
            return isValidated;
        },

        metadataSelected: function (metadataArray, value) {
            if (metadataArray) {
                var arraySize = metadataArray.length;
                for (var i = 0; i < arraySize; i++) {
                    if (metadataArray[i] === value) {
                        return true;
                    }
                }
            }
            return false;
        }
    });

    Y.namespace('Plugin').SearchResultWidgetWizard = SearchResultWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'baseWidgetList',
        'aui-tabview',
        'tabview'
    ]
});
/**
 * This module generates the publication view widget wizard
 *
 * @module publicationViewWidgetWizard
 * @requires baseWidgetList
 */
YUI.add('publicationViewWidgetWizard', function (Y) {

    var

            /**
             * Static constant to refer field 'name'
             *
             * @property FIELD_NAME
             * @type String
             * @static
             * @final
             */
            FIELD_NAME = 'name',

            /**
             * Static constant to refer field 'description'
             *
             * @property FIELD_DESCRIPTION
             * @type String
             * @static
             * @final
             */
            FIELD_DESCRIPTION = 'description',

            /**
             *  Object used to set the MetaTags field types.
             *  Do not modify, MetaTags types are predefined.
             * @type {{TEXT: string, ICON: string, IMAGE: string}}
             * @static
             * @final
             */

            /**
             * Static constant to refer field 'header'
             *
             * @property FIELD_HEADER
             * @type String
             * @static
             * @final
             */
            FIELD_HEADER = 'header',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_FOOTER
             * @type String
             * @static
             * @final
             */
            FIELD_FOOTER = 'footer',

            FIELDTYPE = {TEXT: 'TEXT', ICON: 'ICON', IMAGE: 'IMAGE'},

            METADATA_SELECTION_OBJS = [],
            METADATA_SAVED_OBJS = 'selectedMetaDataFieldType',
            FIELD_LAYOUT = 'layout',

            slideShowLayout = {},

            /**
             * Object used in string replacement on function calls.
             * Can be extended in future with other attributes.
             * @type {{CHECKBOX: string, INPUT: string, RADIO: string}}
             * @static
             * @final
             */

            ELEMENT_TYPE = {
                CHECKBOX: 'CheckboxElement',
                INPUT: 'InputElement',
                RADIO: 'RadioElement'
            },

            /**
             * Static constant to refer field 'cellarIDs'
             *
             * @property FIELD_CELLAR_IDS
             * @type String
             * @static
             * @final
             */
            FIELD_CELLAR_IDS = 'cellarIDs',

            /**
             * Static constant to refer field 'permanentLinks'
             *
             * @property FIELD_PERMANENT_LINKS
             * @type String
             * @static
             * @final
             */
            FIELD_PERMANENT_LINKS = 'permanentLinks',

            /**
             * Object used to set status of elements.
             * Can be extended in the future.
             * @type {{CHECKBOX_STATUS: string, VALUE: string, NAMESPACE: string}}
             * @static
             * @final
             */
            ELEM_ATTR = {
                CHECKBOX_STATUS: 'checked',
                VALUE: 'value',
                NAMESPACE: 'namespace'
            },

            FIELD_SELECTED_METADATA = 'selectedMetadata',


            /**
             * Static constant to refer field 'savedPublications'
             *
             * @property FIELD_SAVED_PUBLICATIONS
             * @type String
             * @static
             * @final
             */
            FIELD_SAVED_PUBLICATIONS = 'savedPublications',

            /**
             * Static constant to refer field 'selectedInformation'
             *
             * @property FIELD_SELECTED_INFORMATION
             * @type String
             * @static
             * @final
             */
            FIELD_SELECTED_INFORMATION = 'defaultOrderElements',

            /**
             * Static constant to refer field 'publicationOrder'
             *
             * @property FIELD_PUBLICATION_ORDER
             * @type String
             * @static
             * @final
             */
            FIELD_PUBLICATION_ORDER = 'publicationOrder',
            METADATA = [{
                value: 'Title',
                key: 'title',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Subtitle',
                key: 'subtitle',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Abstract',
                key: 'abstract',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Date',
                key: 'publishing_date',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Author',
                key: 'authors',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Subject',
                key: 'subjects',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Format',
                key: 'available_formats',
                type: FIELDTYPE.ICON
            }, {
                value: 'Thumbnail',
                key: 'thumbnail',
                type: FIELDTYPE.IMAGE
            }];

    /**
     * Generates the dom and dom events for publication view widget wizard
     *
     * @param cfg
     * @constructor
     * @class PublicationViewWidgetWizard
     * @extends BaseWidgetList
     */
    function PublicationViewWidgetWizard(cfg) {
        PublicationViewWidgetWizard.superclass.constructor.apply(this, arguments);
        this.initSavedObjects(cfg);

    }

    PublicationViewWidgetWizard.NAME = 'PublicationViewWidgetWizard';
    PublicationViewWidgetWizard.NS = 'PublicationViewWidgetWizard';

    PublicationViewWidgetWizard.ATTRS = {
        /**
         * @Deprecated
         *
         * Keeps the cellar ids got from the permanent links
         *
         * @attribute permanentLinks
         * @type Array
         * @default []
         */
        permanentLinks: {
            value: []
        },

        /**
         * Keeps the cellar ids got from my publications
         *
         * @attribute cellarIDs
         * @type Array
         * @default []
         */
        cellarIDs: {
            value: []
        },

        /**
         * Keeps the cellar ids got from saved publications
         *
         * @attribute savedPublications
         * @type Array
         * @default []
         */
        savedPublications: {
            value: []
        },

        /**
         * @Deprecated
         *
         * Keeps the cellar ids got from saved publications and
         * the cellar ids got from the permanent links for the default order sort criteria
         *
         * @attribute defaultOrderElements
         * @type Array
         * @default []
         */
        defaultOrderElements: {
            value: ''
        },

        /**
         * Keeps the publication order
         *
         * @attribute publicationOrder
         * @type Array
         * @default []
         */
        publicationOrder: {
            value: ''
        },

        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },

        /**
         * A list of header options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute header
         * @type {Array}
         * @default []
         */
        header: {
            value: []
        },

        /**
         * A list of footer options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute footer
         * @type {Array}
         * @default []
         */
        footer: {
            value: []
        },

        /**
         * A list of result formats options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute result formats
         * @type {Array}
         * @default []
         */
        resultFormats: {
            value: []
        },
        /**
         *  metadata selection refactoring
         *  array of objects containing selected metadata
         *  each obect has following propertes
         *  key - code of metadata attribute
         *  metadataFieldType - type of metadata attribute
         *  showLabel - value of showLabel checkbox
         *  maxLength - number of characters to be displayed
         *  formatsType - for formats metadata specify if they will be displayed as ICON or TEXT
         *
         * @type {Array}
         */
        selectedMetaDataFieldType: {
            value: []
        }

    };

    Y.extend(PublicationViewWidgetWizard, Y.BaseWidgetList, {

        setWizardType: function () {
            var instance = this;
            instance.set("widgetType", 3);
        },
        setLoadCalls: function () {
            var instance = this;
            instance.set("loadCalls", 1);
        },
        initWizard: function () {
            var instance = this,
                    host = this.get('host');
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general'),
                    instance.t('searchResult.appearance'),
                    instance.t('statistics.publications.details')
                ],
                children: [
                    instance.getGeneralSettings(),
                    instance.getAppearanceSettings(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                        if(instance.get('layoutColumns') && instance.get('layoutRows')) {
                            if ((instance.get('layoutColumns') * instance.get('layoutRows')) > 50 &&
                                Y.one(".message-to-show").hasClass('hidden')) {
                                Y.one(".message-to-show").removeClass('hidden');
                            } else {
                                Y.one(".message-to-show").addClass('hidden');
                            }
                        }
                        instance.validateWidget();
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();
            instance.initLayoutItem();

            new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + "_buttonRow",
                        children: instance.getButtonsBar()
                    })
                ]
            }).render(host);

            instance.fireLoadCallFinished();

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.convertLayoutStyleToJson();
                instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });

        },
        /**
         * This panel displays widget title and the selection of publications that will appear in the widget
         *
         * @method getPropertiesStep
         * @return {PanelElement} the panel with widget properties configuration
         */
        getGeneralSettings: function () {
            var instance = this,
                    host = instance.get('host'),
                    isEdit = instance.get('widgetId') > 0;
            var metadataOpt = instance.getMetadataTranslation();

            var step = new Y.HtmlElement({
                id: 'tab-1',
                cssClass: 'tab-pane active',
                children: [
                    new Y.PanelElement({
                        label: instance.t('publication.properties'),
                        children: [
                            new Y.InputElement({
                                label: instance.t('publication.name'),
                                name: FIELD_NAME,
                                modelInstance: instance,
                                placeholder: instance.t('baseWidgetList.name.placeholder'),
                                cssClass: 'widget-input',
                                required: true,
                                validateFunction: function () {
                                    instance.validateWidget();
                                }
                            }),
                            new Y.InputElement({
                                label: instance.t('publication.description'),
                                name: FIELD_DESCRIPTION,
                                placeholder: instance.t('baseWidgetList.description.placeholder'),
                                modelInstance: instance,
                                cssClass: 'widget-input'
                            }),
                            /**
                             * Language selection option. Automatic option or manual selection of language
                             */
                            instance.getLanguageSelector(),
                            instance.getShowOnlySelectedLanguagePublicationsSelector()
                        ]
                    }),
                    new Y.PanelElement({
                        label: instance.t('publication.publications'),
                        children: [
                            new Y.SelectedPublicationsElement({
                                id: 'selectedPublicationsSelector',
                                cssClass: 'selected-publications-css-class',
                                labels: {
                                    availablePublications: instance.t('publication.availablePublications'),
                                    publicationsTableHeader_no: instance.t('publication.table.no'),
                                    publicationsTableHeader_documentTitle: instance.t('publication.table.documentTitle'),
                                    publicationsTableHeader_format: instance.t('publication.table.format'),
                                    publicationsTableHeader_language: instance.t('publication.table.language'),
                                    addPublication: instance.t('publication.add'),
                                    addPermanentLink: instance.t('publication.addPermanentLink'),
                                    selectedPublications: instance.t('publication.selectedPublications'),
                                    sortBy: instance.t('publication.order')
                                },
                                name: FIELD_SAVED_PUBLICATIONS,
                                fieldSortBy: FIELD_PUBLICATION_ORDER,
                                sortByCriteria: [
                                    {key: '', value: instance.t('publication.order.default')},
                                    {key: 'PUBLICATION_DATE', value: instance.t('publication.order.publicationDate')},
                                    {key: 'AUTHOR', value: instance.t('publication.order.author')},
                                    {key: 'COLLECTION', value: instance.t('publication.order.collection')},
                                    {key: 'SUBJECT', value: instance.t('publication.order.subject')},
                                    {key: 'TITLE', value: instance.t('publication.order.title')}
                                ],
                                fieldCellarIds: FIELD_CELLAR_IDS,
                                fieldCustomOrder: isEdit ? FIELD_SELECTED_INFORMATION : undefined, // backward compatibility
                                fieldPermanentLinks: isEdit ? FIELD_PERMANENT_LINKS : undefined, // backward compatibility
                                modelInstance: instance,
                                getSavedPublicationsURL: Liferay.portal2012[instance.get('namespace') + "myPublicationsUrl"],
                                getMissingPublicationsURL: Liferay.portal2012[instance.get('namespace') + "getPublicationsNames"] +
                                '&' + instance.get('namespace') + 'cellarIds=',
                                myPublicationsPageURL: Liferay.portal2012[instance.get('namespace') + "myPublicationsPageURL"]
                            })
                        ]
                    }),
                    /**
                     * Metadata selection, default metadata.
                     */
                    new Y.HtmlElement({
                        id: instance.get(ELEM_ATTR.NAMESPACE) + "metaselect",
                        wrapperCssClass: 'row',
                        children: [
                            new Y.MetadataEditInTableElement({
                                label: instance.t('baseWidgetList.displayedMetadata'),
                                modelInstance: instance,
                                name: FIELD_SELECTED_METADATA,
                                options: METADATA,
                                displayOrderButton: true
                            })]
                    }),
                    new Y.PanelElement({
                        label: instance.t('publication.targetPage'),
                        children: [
                            instance.getTargetPageStep()
                        ]
                    })
                ]
            });

            return step;
        },

        getStatisticsTable: function () {
            var instance = this, tab;
            var isEdit = instance.get('widgetId') > 0;

            var tableStatistics = [];

            tableStatistics.push(instance.getTableStatistics());

            if (isEdit) {
                tableStatistics.push(instance.getTableDetaliedStatistics());
            }

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: tableStatistics
                    }),
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        // label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        htmlContent: '<a  class="pull-right" href="' + Liferay.portal2012[instance.get('namespace') + "downloadStatisticsPubDetail"] + '">' + instance.t('statistics.download') + '</a>'
                    })
                ]
            });

            return tab;
        },

        getTableStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSelectedPub"],
                    data = [],
                    columns = [],
                    i,
                    len;
            var widgetElement;
            var isEdit = instance.get('widgetId') > 0;


            if (widgetList) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: parseInt(widgetElement.visits),
                        clicks: parseInt(widgetElement.clicksPerm + widgetElement.clicksSearch)
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            if (!isEdit) {
                table.set('rowsPerPage', 25);
                table.set('pageSizes', [10, 25, 50])
                table.set('paginatorLocation', ['footer']);
            }

            return table;
        },

        getTableDetaliedStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSelectedPub"],
                    data = [],
                    columns = [],
                    i, j,
                    len, lenJ;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement, detailsWidgetElement = [];


            if (widgetList) {
                for (i = 0, len = (widgetList.length ); i < len; i++) {
                    if (widgetList[i].publicationStatisticsDTOList) {
                        detailsWidgetElement = widgetList[i].publicationStatisticsDTOList;

                        for (j = 0, lenJ = detailsWidgetElement.length; j < lenJ; j++) {
                            widgetElement = detailsWidgetElement[j];
                            data.push({
                                publications: widgetElement.publication,
                                searchClicks: widgetElement.searchClicks,
                                noImpresions: widgetElement.noImpressions

                            });
                        }
                    }
                }
            }

            columns = [
                {
                    key: 'publications',
                    label: instance.t('statistics.table.publications'),
                    width: '60%',
                    className: 'numeric'
                },
                {
                    key: 'noImpresions',
                    width: '20%',
                    label: instance.t('statistics.table.impressions'),
                    sortable: true
                },
                {
                    key: 'searchClicks',
                    width: '20%',
                    label: instance.t('statistics.table.clicks'),
                    sortable: true
                }

            ];

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 25);
            table.set('pageSizes', [10, 25, 50])
            table.set('paginatorLocation', ['footer']);


            return table;
        },

        getAppearanceSettings: function () {
            var instance = this,
                    tab;

            var layout = instance.getLayoutStep();
            var basicConfiguration = null;
            var advancedConfiguration = null;

            /**
             * Basic config for simple Appearance
             */
            if (instance.get('widgetAppearance') != undefined && instance.get('widgetAppearance') != null) {
                basicConfiguration = instance.get('widgetAppearance');
            }

            /**
             * advanced config for simple Appearance
             */
            if (instance.get('metadataAppearanceList') != undefined && instance.get('metadataAppearanceList') != null) {
                advancedConfiguration = instance.get('metadataAppearanceList');
            }

            /**
             * Slide show edit configuration
             */
            if (instance.get('slideShowLayout') != undefined && instance.get('slideShowLayout') != null) {
                slideShowLayout = instance.getLayoutStyleStep(instance.get('slideShowLayout'));
            }
            else {
                slideShowLayout = instance.getLayoutStyleStep(null);
            }


            /**
             * Appearance settings tab configuration.
             * if parameters for getDisplayAppearence() doesn't exists, provide null as parameter.
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(basicConfiguration, advancedConfiguration, true, true);

            instance.after(FIELD_LAYOUT + "Change", function (e) {
                var instance = e.currentTarget;
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance.after(FIELD_SELECTED_METADATA + "Change", function (e) {
                var instance = e.currentTarget;
                // remove events
                instance._resetLayoutEvents();
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance._addDropDownEvents();
            instance._layoutSet(true);

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline',
                        children: instance.getHeaderFooterOptionList(FIELD_HEADER)
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline',
                        children: instance.getHeaderFooterOptionList(FIELD_FOOTER)
                    }),
                    layout,
                    slideShowLayout,
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });


            return tab;
        },

        getStatistics: function () {
            var instance = this,
                    step, i;

            step = new Y.PanelElement({
                id: 'tab-3',
                label: instance.t('publication.properties')
            })

            return step;
        },

        getButtonsBar: function () {
            var instance = this, toolBar = [];
            var isExistentWidget = (parseInt(instance.get('widgetId')) > 0);
            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' disabled' : ''),
                htmlContent: instance.t('baseWidgetList.save'),
                onClick: function (e) {
                    if (!instance.validateWidget()) {
                        return;
                    }
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertLayoutStyleToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doSaveWidget();
                }
            }));
            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right get-button' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.getCode'),
                onClick: function (e) {
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertLayoutStyleToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doGetWidget();
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.cancel'),
                onClick: function (e) {
                    instance.doReturnToMyWidgets();
                }
            }));

            return toolBar;
        },

        validateWidget: function () {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });

            // validate the product rows*columns <50
            if(instance.get('layoutColumns') && instance.get('layoutRows') && isValidated) {
                if ((instance.get('layoutColumns') * instance.get('layoutRows')) > 50) {
                    isValidated = false;
                }
            }

            if (isValidated) {
                actionButtons.removeClass('disabled');
                actionButtons.set('disabled',false)
            }
            else {
                actionButtons.addClass('disabled');
                actionButtons.set('disabled',true)
            }
            return isValidated;
        }
    });

    Y.namespace('Plugin').PublicationViewWidgetWizard = PublicationViewWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'baseWidgetList'
    ]
});
/**
 * This module generates the publication view widget wizard
 *
 * @module publicationDetailWidgetWizard
 * @requires baseWidgetList
 */
YUI.add('publicationDetailWidgetWizard', function (Y) {

    var

            FIELD_NAME = 'name',
            FIELD_DESCRIPTION = 'description',
            FIELD_SELECTED_METADATA = 'selectedMetadata',
            FIELD_LAYOUT = 'layout',
            FIELD_PERMANENT_LINK = 'permanentLink',

            /**
             *  Object used to set the MetaTags field types.
             *  Do not modify, MetaTags types are predefined.
             * @type {{TEXT: string, ICON: string, IMAGE: string}}
             * @static
             * @final
             */

            FIELDTYPE = {TEXT: 'TEXT', ICON: 'ICON', IMAGE: 'IMAGE'},

            /**
             * Object used to set status of elements.
             * Can be extended in the future.
             * @type {{CHECKBOX_STATUS: string, VALUE: string, NAMESPACE: string}}
             * @static
             * @final
             */
            ELEM_ATTR = {
                CHECKBOX_STATUS: 'checked',
                VALUE: 'value',
                NAMESPACE: 'namespace'
            },


            METADATA = [{
                value: 'Title',
                key: 'title',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Subtitle',
                key: 'subtitle',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Abstract',
                key: 'abstract',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Date',
                key: 'publishing_date',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Author',
                key: 'authors',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Subject',
                key: 'subjects',
                type: FIELDTYPE.TEXT
            }, {
                value: 'Format',
                key: 'available_formats',
                type: FIELDTYPE.ICON
            }, {
                value: 'Thumbnail',
                key: 'thumbnail',
                type: FIELDTYPE.IMAGE
            }],
            FIELD_PUBLICATION_TYPE='publicationType';

    /**
     * Generates the dom and dom events for search result widget wizard
     *
     * @param cfg
     * @constructor
     * @class SearchResultWidgetWizard
     * @extends BaseWidgetList
     */
    function PublicationDetailWidgetWizard(cfg) {
        PublicationDetailWidgetWizard.superclass.constructor.apply(this, arguments);
        this.initSavedObjects(cfg);

    }

    PublicationDetailWidgetWizard.NAME = 'PublicationDetailWidgetWizard';
    PublicationDetailWidgetWizard.NS = 'PublicationDetailWidgetWizard';

    PublicationDetailWidgetWizard.ATTRS = {
        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },
        /**
         * Keeps the source for the results. Can be one of 'widget' or 'source'.
         * If the source is 'widget', then the query will be taken from the parent URL and be passed to the server to display the results.
         *
         * @attribute source
         * @type {String}
         * @default ''
         */
        source: {
            value: " "
        },

        permanentLink: {
            value: ''
        },

        setAppearanceTabs: null,

        selectedMetaDataFieldType: {
            value: []
        },

        metadataAppearanceList: {
            value: []
        },

        widgetAppearance: {
            value: {}
        },


        /**
         * A list of result formats options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute result formats
         * @type {Array}
         * @default []
         */
        resultFormats: {
            value: []
        },
        /**
         * Keep the publication type. It should either be null/blank or 'elif'
         */
        publicationType :{value:''}

    };

    Y.extend(PublicationDetailWidgetWizard, Y.BaseWidgetList, {
        /**
         * Initialization of the inner tabs.
         */
        initWizard: function () {
            var instance = this,
                    host = this.get('host');
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general'),
                    instance.t('searchResult.appearance'),
                    instance.t('statistics.publications.details')
                ],
                children: [
                    instance.getGeneralSettings(),
                    instance.getAppearanceSettings(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();
            instance.initLayoutItem();

            /**
             * Button bar present at footer for all tabs.
             */

            new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + "_buttonRow",
                        children: instance.getButtonsBar()
                    })
                ]
            }).render(host);

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });

            instance.validateWidget();
        },

        getMetadataStep: function () {
            var instance = this, options = [], i;

            for (i = 0; i < METADATA.length; i++) {
                options.push({
                    key: METADATA[i].key,
                    value: instance.t('baseWidgetList.' + METADATA[i].key)
                })
            }
            return options;
        },

        /**
         * First tab creation.
         * @returns {Y.PanelElement}
         */

        getGeneralSettings: function () {
            var instance = this, tab;
            var metadataOpt = instance.getMetadataStep();

            let metadataEditInTableElement = new Y.MetadataEditInTableElement({
                label: instance.t('baseWidgetList.displayedMetadata'),
                modelInstance: instance,
                name: FIELD_SELECTED_METADATA,
                options: METADATA,
                displayOrderButton: true
            });

            (metadataEditInTableElement.get('children')[0]).get('children').push(instance.getViewThisSelector());
            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane active',
                id: 'tab-1',
                children: [
                    new Y.InputElement({
                        label: instance.t('searchResult.name'),
                        name: FIELD_NAME,
                        modelInstance: instance,
                        placeholder: instance.t('baseWidgetList.name.placeholder'),
                        cssClass: 'widget-input',
                        required: true,
                        validateFunction: function () {
                            instance.validateWidget();
                        }
                    }),
                    new Y.InputElement({
                        label: instance.t('searchResult.description'),
                        name: FIELD_DESCRIPTION,
                        placeholder: instance.t('baseWidgetList.description.placeholder'),
                        modelInstance: instance,
                        cssClass: 'widget-input'
                    }),
                    /**
                     * Language selection option. Automatic option or manual selection of language
                     */
                    instance.getLanguageSelector(),

                    /**
                     * Metadata selection, default metadata.
                     */
                    new Y.HtmlElement({
                        id: instance.get(ELEM_ATTR.NAMESPACE) + "metaselect",
                        wrapperCssClass: 'row',
                        children: [
                            metadataEditInTableElement
                        ]
                    }),
                    new Y.PanelElement({
                        label: instance.t('publication.publication'),
                        children: [
                            new Y.SelectedPublicationsElement({
                                id: 'publicationSelector',
                                labels: {
                                    publicationsTableHeader_no: instance.t('publication.table.no'),
                                    publicationsTableHeader_documentTitle: instance.t('publication.table.documentTitle'),
                                    publicationsTableHeader_format: instance.t('publication.table.format'),
                                    publicationsTableHeader_language: instance.t('publication.table.language'),
                                    publicationsTableHeader_publicationType: instance.t('publication.table.publicationType'),
                                    addPublication: instance.t('publication.add'),
                                    addPermanentLink: instance.t('publication.addPermanentLink'),
                                    selectedPublications: instance.t('publication.selectedPublication'),
                                    optionNoPreSelected: instance.t('publicationDetails.noPreselected'),
                                    optionPreSelected: instance.t('publicationDetails.preselected')
                                },
                                singlePublication: true,
                                name: FIELD_PERMANENT_LINK,
                                fieldCellarIds: FIELD_PERMANENT_LINK,
                                modelInstance: instance,
                                getSavedPublicationsURL: Liferay.portal2012[instance.get('namespace') + "myPublicationsUrl"],
                                getMissingPublicationsURL: Liferay.portal2012[instance.get('namespace') + "getPublicationsNames"] +
                                '&' + instance.get('namespace') + 'cellarIds=',
                                myPublicationsPageURL: Liferay.portal2012[instance.get('namespace') + "myPublicationsPageURL"]
                            })
                        ]
                    })
                    //,instance.getViewThisSelector()
                ]
            });

            return tab;
        },


        getAppearanceSettings: function () {
            var instance = this,
                    tab;

            var layout = instance.getLayoutStep();

            /**
             * getDisplayAppearence() must have null as aprameters in order to work.
             * @type {Y.TabView}
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(null, null, true, true);

            instance.after(FIELD_LAYOUT + "Change", function (e) {
                var instance = e.currentTarget;
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance.after(FIELD_SELECTED_METADATA + "Change", function (e) {
                var instance = e.currentTarget;
                // remove events
                instance._resetLayoutEvents();
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance._addDropDownEvents();
            instance._layoutSet(true);

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    layout,
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });

            instance.fireLoadCallFinished();

            instance._addDropDownEvents();
            instance._layoutSet(true);
            return tab;
        },

        getStatisticsTable: function () {
            var instance = this, tab;
            var isEdit = instance.get('widgetId') > 0;

            var tableStatistics = [];

            tableStatistics.push(instance.getTableStatistics());

            if (isEdit) {
                tableStatistics.push(instance.getTableDetaliedStatistics());
            }

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: tableStatistics
                    }),
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        // label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        htmlContent: '<a  class="pull-right" href="' + Liferay.portal2012[instance.get('namespace') + "downloadStatisticsSelectedPub"] + '">' + instance.t('statistics.download') + '</a>'
                    })
                ]
            });

            return tab;
        },

        getTableStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListPublicationDetail"],
                    data = [],
                    columns = [],
                    i,
                    len;
            var widgetElement;
            var isEdit = instance.get('widgetId') > 0;

            if (widgetList && widgetList.length > 0) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: parseInt(widgetElement.visits),
                        clicks: parseInt(widgetElement.clicksPerm + widgetElement.clicksSearch)
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            if (!isEdit) {
                table.set('rowsPerPage', 25);
                table.set('pageSizes', [10, 25, 50])
                table.set('paginatorLocation', ['footer']);
            }

            return table;
        },

        getTableDetaliedStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListPublicationDetail"],
                    data = [],
                    columns = [],
                    i, j,
                    len, lenJ;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement, detailsWidgetElement = [];


            for (i = 0, len = (widgetList.length - 1); i < len; i++) {
                if (widgetList[i].publicationStatisticsDTOList) {
                    detailsWidgetElement = widgetList[i].publicationStatisticsDTOList;

                    for (j = 0, lenJ = detailsWidgetElement.length; j < lenJ; j++) {
                        widgetElement = detailsWidgetElement[j];
                        data.push({
                            publications: widgetElement.publication,
                            searchClicks: widgetElement.searchClicks,
                            noImpresions: widgetElement.noImpressions

                        });
                    }
                }
            }

            columns = [
                {
                    key: 'publications',
                    label: instance.t('statistics.table.publications'),
                    width: '60%',
                    className: 'numeric'
                },
                {
                    key: 'noImpresions',
                    width: '20%',
                    label: instance.t('statistics.table.impressions'),
                    sortable: true
                },
                {
                    key: 'searchClicks',
                    width: '20%',
                    label: instance.t('statistics.table.clicks'),
                    sortable: true
                }

            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 25);
            table.set('pageSizes', [10, 25, 50])
            table.set('paginatorLocation', ['footer']);


            return table;
        },


        getStatistics: function () {
            var instance = this,
                    tab,
                    isEdit = instance.get('widgetId') > 0;

            tab = new Y.PanelElement({
                wrapperCssClass: 'step step-2 hide',
                children: []
            });

            return tab;
        },

        getButtonsBar: function () {
            var instance = this, toolBar = [];
            var isExistentWidget = (parseInt(instance.get('widgetId')) > 0);
            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' disabled' : ''),
                htmlContent: instance.t('baseWidgetList.save'),
                onClick: function (e) {
                    if (!instance.validateWidget()) {
                        return;
                    }
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doSaveWidget();
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right get-button' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.getCode'),
                onClick: function (e) {
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doGetWidget()
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.cancel'),
                onClick: function (e) {
                    instance.doReturnToMyWidgets();
                }
            }));

            return toolBar;
        },

        getBasicAppearence: function () {
            var instance = this;
            var element;

            element = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-inner-1',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline'
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline'
                    })
                ]
            });

            return element;

        },


        getAdvancedAppearence: function () {
            var instance = this;
            var element;

            element = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-inner-2',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline'
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline'
                    })
                ]
            });

            return element;

        },

        setWizardType: function () {
            var instance = this;
            instance.set("widgetType", 5);
        },
        setLoadCalls: function () {
            var instance = this;
            instance.set("loadCalls", 1);
        },

        validateWidget: function () {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });

            if (isValidated) {
                actionButtons.removeClass('disabled');
            }
            else {
                actionButtons.addClass('disabled');
            }
            return isValidated;
        }
    });

    Y.namespace('Plugin').PublicationDetailWidgetWizard = PublicationDetailWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'baseWidgetList',
        'aui-tabview',
        'tabview'
    ]
});
/**
 * This module generates the public procurement details widget
 *
 * @module publicProcurementDetailsWidgetWizard
 * @requires baseWidgetList
 */
YUI.add('publicProcurementDetailsWidgetWizard', function (Y) {

    var

            FIELD_NAME = 'name',
            FIELD_DESCRIPTION = 'description',
            FIELD_SELECTED_METADATA = 'selectedMetadata',
            FIELD_LAYOUT = 'layout',
            FIELD_PERMANENT_LINK = 'permanentLink',

            /**
             *  Object used to set the MetaTags field types.
             *  Do not modify, MetaTags types are predefined.
             * @type {{TEXT: string, ICON: string, IMAGE: string}}
             * @static
             * @final
             */

            FIELDTYPE = {TEXT: 'TEXT', ICON: 'ICON', IMAGE: 'IMAGE'},

            /**
             * Object used to set status of elements.
             * Can be extended in the future.
             * @type {{CHECKBOX_STATUS: string, VALUE: string, NAMESPACE: string}}
             * @static
             * @final
             */
            ELEM_ATTR = {
                CHECKBOX_STATUS: 'checked',
                VALUE: 'value',
                NAMESPACE: 'namespace'
            },


        METADATA = [{
            value: 'Title',
            key: 'title',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Description',
            key: 'description',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Published',
            key: 'published_date',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Submission deadline',
            key: 'submission_deadline',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Status',
            key: 'status',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Buyer',
            key: 'buyer',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Estimated contract value',
            key: 'estimated_contract_value',
            type: FIELDTYPE.TEXT
        }, {
            value: 'CPV Code',
            key: 'business_sector',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Place of performance (NUTS)',
            key: 'nuts',
            type: FIELDTYPE.TEXT
        }],
            FIELD_PUBLICATION_TYPE='publicationType';

    /**
     * Generates the dom and dom events for search result widget wizard
     *
     * @param cfg
     * @constructor
     * @class SearchResultWidgetWizard
     * @extends BaseWidgetList
     */
    function PublicProcurementDetailsWidgetWizard(cfg) {
        PublicProcurementDetailsWidgetWizard.superclass.constructor.apply(this, arguments);
        this.initSavedObjects(cfg);

    }

    PublicProcurementDetailsWidgetWizard.NAME = 'PublicProcurementDetailsWidgetWizard';
    PublicProcurementDetailsWidgetWizard.NS = 'PublicProcurementDetailsWidgetWizard';

    PublicProcurementDetailsWidgetWizard.ATTRS = {
        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },
        /**
         * Keeps the source for the results. Can be one of 'widget' or 'source'.
         * If the source is 'widget', then the query will be taken from the parent URL and be passed to the server to display the results.
         *
         * @attribute source
         * @type {String}
         * @default ''
         */
        source: {
            value: " "
        },

        permanentLink: {
            value: ''
        },

        setAppearanceTabs: null,

        selectedMetaDataFieldType: {
            value: [
                {
                    "key": "title",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": false
                },
                {
                    "key": "description",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": false
                },
                {
                    "key": "published_date",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "submission_deadline",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "status",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "buyer",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "estimated_contract_value",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "business_sector",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "nuts",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "align": "left",
                    "key": "shareButton",
                    "maxItems": 0,
                    "maxLength": 0,
                    "showLabel": false
                }
            ]
        },

        metadataAppearanceList: {
            value: []
        },

        widgetAppearance: {
        },

        /**
         * A list of result formats options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute result formats
         * @type {Array}
         * @default []
         */
        resultFormats: {
            value: []
        },
        /**
         * Keep the publication type. It should either be null/blank or 'elif'
         */
        publicationType :{value:''}

    };

    Y.extend(PublicProcurementDetailsWidgetWizard, Y.BaseWidgetList, {
        /**
         * Initialization of the inner tabs.
         */
        initWizard: function () {
            var instance = this,
                    host = this.get('host');
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general'),
                    instance.t('searchResult.appearance'),
                    instance.t('statistics.publications.details')
                ],
                children: [
                    instance.getGeneralSettings(),
                    instance.getAppearanceSettings(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();
            instance.initLayoutItem();

            /**
             * Button bar present at footer for all tabs.
             */

            new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + "_buttonRow",
                        children: instance.getButtonsBar()
                    })
                ]
            }).render(host);

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });

            instance.validateWidget();
        },

        getMetadataStep: function () {
            var instance = this, options = [], i;

            for (i = 0; i < METADATA.length; i++) {
                options.push({
                    key: METADATA[i].key,
                    value: instance.t('baseWidgetList.' + METADATA[i].key)
                })
            }
            return options;
        },

        /**
         * First tab creation.
         * @returns {Y.PanelElement}
         */

        getGeneralSettings: function () {
            var instance = this, tab;
            var metadataOpt = instance.getMetadataStep();

            let metadataEditInTableElement = new Y.MetadataEditInTableElement({
                label: instance.t('baseWidgetList.displayedMetadata'),
                modelInstance: instance,
                name: FIELD_SELECTED_METADATA,
                options: METADATA,
                displayOrderButton: false
            });

            (metadataEditInTableElement.get('children')[0]).get('children').push(instance.getViewThisSelector());
            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane active',
                id: 'tab-1',
                children: [
                    new Y.InputElement({
                        label: instance.t('searchResult.name'),
                        name: FIELD_NAME,
                        modelInstance: instance,
                        placeholder: instance.t('baseWidgetList.name.placeholder'),
                        cssClass: 'widget-input',
                        required: true,
                        validateFunction: function () {
                            instance.validateWidget();
                        }
                    }),
                    new Y.InputElement({
                        label: instance.t('searchResult.description'),
                        name: FIELD_DESCRIPTION,
                        placeholder: instance.t('baseWidgetList.description.placeholder'),
                        modelInstance: instance,
                        cssClass: 'widget-input'
                    }),
                    /**
                     * Language selection option. Automatic option or manual selection of language
                     */
                    instance.getLanguageSelector(),

                    /**
                     * Metadata selection, default metadata.
                     */
                    new Y.HtmlElement({
                        id: instance.get(ELEM_ATTR.NAMESPACE) + "metaselect",
                        wrapperCssClass: 'row',
                        children: [
                            metadataEditInTableElement
                        ]
                    }),
                    new Y.PanelElement({
                        label: instance.t('publication.publication'),
                        children: [
                            new Y.SelectedPublicationsElement({
                                id: 'publicationSelector',
                                labels: {
                                    publicationsTableHeader_no: instance.t('publication.table.no'),
                                    publicationsTableHeader_documentTitle: instance.t('publication.table.documentTitle'),
                                    publicationsTableHeader_format: instance.t('publication.table.format'),
                                    publicationsTableHeader_language: instance.t('publication.table.language'),
                                    publicationsTableHeader_publicationType: instance.t('publication.table.publicationType'),
                                    addPublication: instance.t('publication.add'),
                                    addPermanentLink: instance.t('publication.addPermanentLink'),
                                    selectedPublications: instance.t('publication.selectedPublication'),
                                    optionNoPreSelected: instance.t('publicationDetails.noPreselected'),
                                    optionPreSelected: instance.t('publicationDetails.preselected')
                                },
                                singlePublication: true,
                                name: FIELD_PERMANENT_LINK,
                                fieldCellarIds: FIELD_PERMANENT_LINK,
                                modelInstance: instance,
                                getSavedPublicationsURL: Liferay.portal2012[instance.get('namespace') + "myPublicationsUrl"],
                                getMissingPublicationsURL: Liferay.portal2012[instance.get('namespace') + "getPublicationsNames"] +
                                '&' + instance.get('namespace') + 'cellarIds=',
                                myPublicationsPageURL: Liferay.portal2012[instance.get('namespace') + "myPublicationsPageURL"]
                            })
                        ]
                    })
                    //,instance.getViewThisSelector()
                ]
            });

            return tab;
        },


        getAppearanceSettings: function () {
            var instance = this,
                    tab;

            var layout = instance.getLayoutStep();

            /**
             * getDisplayAppearence() must have null as aprameters in order to work.
             * @type {Y.TabView}
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(null, null, true, true);

            instance.after(FIELD_LAYOUT + "Change", function (e) {
                var instance = e.currentTarget;
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance.after(FIELD_SELECTED_METADATA + "Change", function (e) {
                var instance = e.currentTarget;
                // remove events
                instance._resetLayoutEvents();
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance._addDropDownEvents();
            instance._layoutSet(true);

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    layout,
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });

            instance.fireLoadCallFinished();

            instance._addDropDownEvents();
            instance._layoutSet(true);
            return tab;
        },

        getStatisticsTable: function () {
            var instance = this, tab;
            var isEdit = instance.get('widgetId') > 0;

            var tableStatistics = [];

            tableStatistics.push(instance.getTableStatistics());

            if (isEdit) {
                tableStatistics.push(instance.getTableDetaliedStatistics());
            }

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: tableStatistics
                    }),
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        // label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        htmlContent: '<a  class="pull-right" href="' + Liferay.portal2012[instance.get('namespace') + "downloadStatisticsSelectedPub"] + '">' + instance.t('statistics.download') + '</a>'
                    })
                ]
            });

            return tab;
        },

        getTableStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListPublicationDetail"],
                    data = [],
                    columns = [],
                    i,
                    len;
            var widgetElement;
            var isEdit = instance.get('widgetId') > 0;

            if (widgetList && widgetList.length > 0) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: parseInt(widgetElement.visits),
                        clicks: parseInt(widgetElement.clicksPerm + widgetElement.clicksSearch)
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            if (!isEdit) {
                table.set('rowsPerPage', 25);
                table.set('pageSizes', [10, 25, 50])
                table.set('paginatorLocation', ['footer']);
            }

            return table;
        },

        getTableDetaliedStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListPublicationDetail"],
                    data = [],
                    columns = [],
                    i, j,
                    len, lenJ;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement, detailsWidgetElement = [];


            for (i = 0, len = (widgetList.length - 1); i < len; i++) {
                if (widgetList[i].publicationStatisticsDTOList) {
                    detailsWidgetElement = widgetList[i].publicationStatisticsDTOList;

                    for (j = 0, lenJ = detailsWidgetElement.length; j < lenJ; j++) {
                        widgetElement = detailsWidgetElement[j];
                        data.push({
                            publications: widgetElement.publication,
                            searchClicks: widgetElement.searchClicks,
                            noImpresions: widgetElement.noImpressions

                        });
                    }
                }
            }

            columns = [
                {
                    key: 'publications',
                    label: instance.t('statistics.table.publications'),
                    width: '60%',
                    className: 'numeric'
                },
                {
                    key: 'noImpresions',
                    width: '20%',
                    label: instance.t('statistics.table.impressions'),
                    sortable: true
                },
                {
                    key: 'searchClicks',
                    width: '20%',
                    label: instance.t('statistics.table.clicks'),
                    sortable: true
                }

            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 25);
            table.set('pageSizes', [10, 25, 50])
            table.set('paginatorLocation', ['footer']);


            return table;
        },


        getStatistics: function () {
            var instance = this,
                    tab,
                    isEdit = instance.get('widgetId') > 0;

            tab = new Y.PanelElement({
                wrapperCssClass: 'step step-2 hide',
                children: []
            });

            return tab;
        },

        getButtonsBar: function () {
            var instance = this, toolBar = [];
            var isExistentWidget = (parseInt(instance.get('widgetId')) > 0);
            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' disabled' : ''),
                htmlContent: instance.t('baseWidgetList.save'),
                onClick: function (e) {
                    if (!instance.validateWidget()) {
                        return;
                    }
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doSaveWidget();
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right get-button' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.getCode'),
                onClick: function (e) {
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doGetWidget()
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.cancel'),
                onClick: function (e) {
                    instance.doReturnToMyWidgets();
                }
            }));

            return toolBar;
        },

        getBasicAppearence: function () {
            var instance = this;
            var element;

            element = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-inner-1',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline'
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline'
                    })
                ]
            });

            return element;

        },


        getAdvancedAppearence: function () {
            var instance = this;
            var element;

            element = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-inner-2',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline'
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline'
                    })
                ]
            });

            return element;

        },

        setWizardType: function () {
            var instance = this;
            instance.set("widgetType", 10);
        },
        setLoadCalls: function () {
            var instance = this;
            instance.set("loadCalls", 1);
        },

        validateWidget: function () {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });

            if (isValidated) {
                actionButtons.removeClass('disabled');
            }
            else {
                actionButtons.addClass('disabled');
            }
            return isValidated;
        }
    });

    Y.namespace('Plugin').PublicProcurementDetailsWidgetWizard = PublicProcurementDetailsWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'baseWidgetList',
        'aui-tabview',
        'tabview'
    ]
});
window.SELECT_ORGANIZATION_WIDGET_PRESENT = true;
/**
 * This module generates the select organization widget
 *
 * @module selectOrganizationWidget
 * @requires wizardTools
 */

YUI.add('selectOrganizationWidget', function(Y) {
    var
        /**
         * Static constant to refer field 'name'
         *
         * @property FIELD_NAME
         * @type String
         * @static
         * @final
         */
        FIELD_NAME = 'name',
        BASE_ORGANIZATION = 'PUBL/PUBL';

    /**
     * Generates the dom and dom events for search box wizard
     *
     * @param cfg
     * @constructor
     * @class SelectOrganizationWidget
     * @extends AbstractWizard
     */
    function SelectOrganizationWidget(cfg){
        SelectOrganizationWidget.superclass.constructor.apply(this, arguments);
    }

    SelectOrganizationWidget.NAME = 'SelectOrganizationWidget';
    SelectOrganizationWidget.NS = 'SelectOrganizationWidget';

    SelectOrganizationWidget.ATTRS = {

        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value:''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value:''
        },

        baseOrganization: {
            value: ''
        },
        locale: {
            value: ''
        },
        validator: {
            value: function() {}
        },
        currentValue: {
            value: ''
        }

    };


    SelectOrganizationWidget.TREE_LOADED_EVENT = 'treeLoadedEvent';
    SelectOrganizationWidget.TREE_UPDATED_EVENT = 'treeUpdatedEvent';

    Y.extend(SelectOrganizationWidget, Y.HtmlElement, {
        globalTree: null,
        _afterRenderEventHandler: null,
        initializer: function () {
            var instance = this;
            baseOrganization = instance.get('baseOrganization');
            locale = instance.get('locale');
            validator = instance.get('validator');

            var children = [];
            children.push(new Y.HtmlElement({
                cssClass: 'row table-holder',
                htmlContent: '<div id="blocking-loader" class="portal-loader" aria-busy="true">' +
                '<span class="loading-image"></span>' +
                '</div>'
            }));

            instance.set('children', children);
            Y.on('io:complete', instance._ioFilter, Y, {});
        },
        _ioFilter: function(id, o, args) {
            var instance = this;
            if(o.response.indexOf("wiw-webservice/sublevels") !== -1) {
                var payload = JSON.parse(o.response);
                Y.fire(SelectOrganizationWidget.TREE_UPDATED_EVENT, {
                    currentTarget: instance,
                    options: payload
                });
            }

        },
        getCodeFromUrl: function(url) {
            var regexp = /\?WIW_ORGANIZATION_DETAIL_COMBINED_URL_PARAM=(.*?)&/;
            return regexp.exec(url)[1];
        },
        getPathToNode: function(node) {
            var instance = this;
            var parent = node;
            var aPath = [];
            while(parent != null && parent.getAttrs().io != null) {
                aPath.push(instance.getCodeFromUrl(parent.getAttrs().io.url));
                parent = parent.getAttrs().parentNode;
            }

            return aPath.reverse();
        },
        getSelectedElement: function() {
            var instance = this;
            var selectedElement = null;
            if(instance.globalTree !=null) {

                var findChecked = function(parent) {
                    var attrs = parent.getAttrs();
                    if(attrs.checked) {
                        return {
                            label: attrs.label,
                            code: instance.getCodeFromUrl(attrs.io.url),
                            path: instance.getPathToNode(parent)
                        }
                    } else if(attrs.children.length > 0 ){
                        for(var i = 0; i < attrs.children.length; i ++) {
                            var returnedValue = findChecked(attrs.children[i]);
                            if(returnedValue != null) {
                                return returnedValue;
                            }
                        }
                    }

                    return null;
                }

                instance.globalTree.eachChildren(function(child){
                    if(selectedElement == null) {
                        selectedElement = findChecked(child);
                    }
                });
            }

            return selectedElement;
        },
        loadTree: function() {
            var instance = this;
            //making the ajax call to load the whole tree
            var sGetSublevelsUrl = '/o/wiw-webservice/sublevels?WIW_ORGANIZATION_DETAIL_COMBINED_URL_PARAM=' + baseOrganization + '&WIW_ORGANIZATION_DETAIL_LOCALE_PARAM=' + locale + '&WIW_ORGANIZATION_DETAIL_LIST_TYPE_PARAM=RADIO';
                Y.io.request(sGetSublevelsUrl, {
                    dataType: 'json',
                    method: 'POST',
                    data: {},
                    on: {
                        success: function () {
                            var json = this.get('responseData');
                            Y.fire(SelectOrganizationWidget.TREE_LOADED_EVENT, {
                                currentTarget: instance,
                                options: json
                            });
                        }
                    }
                });

        },
        renderTree: function(treeData) {
            var instance = this;
            var host = instance.get('host');
            if(Y.one('#blocking-loader')) {
                Y.one('#blocking-loader').remove();
            }
           //A.TreeNode.ATTRS.cssClasses.value.normal.iconHitAreaCollapsed = 'op-icon op-icon-plus tree-hitarea';
           // A.TreeNode.ATTRS.cssClasses.value.normal.iconHitAreaExpanded = 'op-icon op-icon-less tree-hitarea';
            //A.TreeNode.ATTRS.cssClasses.value.normal.iconLeaf = 'op-icon op-icon-op-bullet-wiw';
            var after = {};
            var currentValue = instance.get('currentValue');
            var aSplited = [];
            if(currentValue != null && currentValue.length > 0) {
                var aSplited = currentValue;
                var LoadIterator = function(values) {

                    var checkList = function(childrenList, elementToFind, elementsLength) {
                        var actionTaken = false;
                        Y.Array.each(childrenList, function(child, index) {
                            var currentCode = instance.getCodeFromUrl(child.getAttrs().io.url);
                            if (currentCode == elementToFind) {
                                //when found the one to click
                                if (LoadIterator.prototype.NEXT_INDEX == elementsLength - 1) {
                                    child._getStateVal('boundingBox').one('.icon-ok-sign').simulate('click');
                                    LoadIterator.prototype.HAS_FINISHED = true;
                                    actionTaken = true;
                                } else {
                                    //when found the one to open
                                    LoadIterator.prototype.NEXT_INDEX++;
                                    child._getStateVal('boundingBox').one('.tree-hitarea').simulate('click');
                                    actionTaken = true;
                                }
                            }

                            if(!actionTaken) {
                                var children = child.getChildren();
                                if(children.length > 0) {
                                    actionTaken = checkList(children, elementToFind, elementsLength);
                                }
                            }
                        });


                        return actionTaken;
                    }

                    this.setup = function() {
                        if(!LoadIterator.prototype.HAS_FINISHED) {
                            var elementToFind = values[LoadIterator.prototype.NEXT_INDEX];
                            //we need to find it in the current level and select it if it is the last

                            var treeChildren = instance.globalTree.getChildren();
                            checkList(treeChildren, elementToFind, values.length);
                        }
                    }
                }

                LoadIterator.prototype = {
                    HAS_FINISHED: false,
                    NEXT_INDEX: 0,
                    VALUES: aSplited
                }


                after = {
                    '*:expandedChange': function(e) {
                        var iterator = new LoadIterator(aSplited);
                        iterator.setup();
                    }
                }
            } else {
                after = {
                    '*:expandedChange': function(e) {
                    }
                }
            }

            instance.globalTree = new Y.TreeView(
                {
                    type: 'normal',
                    boundingBox: host,
                    children: treeData,
                    after: after,
                    //children: root
                    //lazyLoad: true,
                    /*
                    io: {
                        cfg: {
                            data: function (node) {
                                return {
                                    parentId: node.get('id')
                                };
                            },
                            method: A.config.io.method
                        },
                        url: _this.options.fragmentUrl
                    }*/
                });
            instance.globalTree.on('click',  function(e){
                var validator = instance.get('validator');
                validator();
            });

            instance.globalTree.render();

            if(aSplited.length > 0) {
                var iterator = new LoadIterator(aSplited);
                iterator.setup();
            }
        },
        destructWizard : function(){
            if(this.globalTree != null) {
                this.globalTree.destroy();
                this.globalTree = null;
            }

            if(this._afterRenderEventHandler != null) {
                this._afterRenderEventHandler.detach();
            }
        },
        addAfterRenderEvents: function () {
            this.loadTree();
            this._afterRenderEventHandler = Y.on(SelectOrganizationWidget.TREE_LOADED_EVENT, function (e) {
                var instance = e.currentTarget;
                instance.renderTree(e.options);
                return false;
            });

        }
    });

    Y.SelectOrganizationWidget = SelectOrganizationWidget;

}, 'portalop-2014.05.28-17-20', {
    requires:
        [
            'node',
            'base-build',
            'plugin',
            'classnamemanager',
            'attribute-base',
            'io-base',
            'history-hash',
            'wizardTools',
            'formWidget',
            'dd-constrain',
            'dd-proxy',
            'dd-drop',
            'autocomplete',
            'datatype',
            'node-event-simulate',
            'aui-tree-view'
        ]
});
/**
 * This module generates the public procurement selected procurements widget
 *
 * @module publicProcurementSelectedWidgetWizard
 * @requires baseWidgetList
 */
YUI.add('publicProcurementSelectedWidgetWizard', function (Y) {

    var

            /**
             * Static constant to refer field 'name'
             *
             * @property FIELD_NAME
             * @type String
             * @static
             * @final
             */
            FIELD_NAME = 'name',

            /**
             * Static constant to refer field 'description'
             *
             * @property FIELD_DESCRIPTION
             * @type String
             * @static
             * @final
             */
            FIELD_DESCRIPTION = 'description',

            /**
             *  Object used to set the MetaTags field types.
             *  Do not modify, MetaTags types are predefined.
             * @type {{TEXT: string, ICON: string, IMAGE: string}}
             * @static
             * @final
             */

            /**
             * Static constant to refer field 'header'
             *
             * @property FIELD_HEADER
             * @type String
             * @static
             * @final
             */
            FIELD_HEADER = 'header',

            /**
             * Static constant to refer field 'footer'
             *
             * @property FIELD_FOOTER
             * @type String
             * @static
             * @final
             */
            FIELD_FOOTER = 'footer',

            FIELDTYPE = {TEXT: 'TEXT', ICON: 'ICON', IMAGE: 'IMAGE'},

            METADATA_SELECTION_OBJS = [],
            METADATA_SAVED_OBJS = 'selectedMetaDataFieldType',
            FIELD_LAYOUT = 'layout',

            slideShowLayout = {},

            /**
             * Object used in string replacement on function calls.
             * Can be extended in future with other attributes.
             * @type {{CHECKBOX: string, INPUT: string, RADIO: string}}
             * @static
             * @final
             */

            ELEMENT_TYPE = {
                CHECKBOX: 'CheckboxElement',
                INPUT: 'InputElement',
                RADIO: 'RadioElement'
            },

            /**
             * Static constant to refer field 'cellarIDs'
             *
             * @property FIELD_CELLAR_IDS
             * @type String
             * @static
             * @final
             */
            FIELD_CELLAR_IDS = 'cellarIDs',

            /**
             * Static constant to refer field 'permanentLinks'
             *
             * @property FIELD_PERMANENT_LINKS
             * @type String
             * @static
             * @final
             */
            FIELD_PERMANENT_LINKS = 'permanentLinks',

            /**
             * Object used to set status of elements.
             * Can be extended in the future.
             * @type {{CHECKBOX_STATUS: string, VALUE: string, NAMESPACE: string}}
             * @static
             * @final
             */
            ELEM_ATTR = {
                CHECKBOX_STATUS: 'checked',
                VALUE: 'value',
                NAMESPACE: 'namespace'
            },

            FIELD_SELECTED_METADATA = 'selectedMetadata',


            /**
             * Static constant to refer field 'savedPublications'
             *
             * @property FIELD_SAVED_PUBLICATIONS
             * @type String
             * @static
             * @final
             */
            FIELD_SAVED_PUBLICATIONS = 'savedPublications',

            /**
             * Static constant to refer field 'selectedInformation'
             *
             * @property FIELD_SELECTED_INFORMATION
             * @type String
             * @static
             * @final
             */
            FIELD_SELECTED_INFORMATION = 'defaultOrderElements',

            /**
             * Static constant to refer field 'publicationOrder'
             *
             * @property FIELD_PUBLICATION_ORDER
             * @type String
             * @static
             * @final
             */
            FIELD_PUBLICATION_ORDER = 'publicationOrder',
        METADATA = [{
            value: 'Title',
            key: 'title',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Description',
            key: 'description',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Published',
            key: 'published_date',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Submission deadline',
            key: 'submission_deadline',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Status',
            key: 'status',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Type of contract',
            key: 'type_of_contract',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Buyer',
            key: 'buyer',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Estimated contract value',
            key: 'estimated_contract_value',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Main CPV Code',
            key: 'main_cpv',
            type: FIELDTYPE.TEXT
        }, {
            value: 'Place of performance (NUTS)',
            key: 'nuts',
            type: FIELDTYPE.TEXT
        }];

    /**
     * Generates the dom and dom events for publication view widget wizard
     *
     * @param cfg
     * @constructor
     * @class PublicProcurementSelectedWidgetWizard
     * @extends BaseWidgetList
     */
    function PublicProcurementSelectedWidgetWizard(cfg) {
        PublicProcurementSelectedWidgetWizard.superclass.constructor.apply(this, arguments);
        this.initSavedObjects(cfg);

    }

    PublicProcurementSelectedWidgetWizard.NAME = 'PublicProcurementSelectedWidgetWizard';
    PublicProcurementSelectedWidgetWizard.NS = 'PublicProcurementSelectedWidgetWizard';

    PublicProcurementSelectedWidgetWizard.ATTRS = {
        /**
         * @Deprecated
         *
         * Keeps the cellar ids got from the permanent links
         *
         * @attribute permanentLinks
         * @type Array
         * @default []
         */
        permanentLinks: {
            value: []
        },

        /**
         * Keeps the cellar ids got from my publications
         *
         * @attribute cellarIDs
         * @type Array
         * @default []
         */
        cellarIDs: {
            value: []
        },

        /**
         * Keeps the cellar ids got from saved publications
         *
         * @attribute savedPublications
         * @type Array
         * @default []
         */
        savedPublications: {
            value: []
        },

        /**
         * @Deprecated
         *
         * Keeps the cellar ids got from saved publications and
         * the cellar ids got from the permanent links for the default order sort criteria
         *
         * @attribute defaultOrderElements
         * @type Array
         * @default []
         */
        defaultOrderElements: {
            value: ''
        },

        /**
         * Keeps the publication order
         *
         * @attribute publicationOrder
         * @type Array
         * @default []
         */
        publicationOrder: {
            value: ''
        },

        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },

        /**
         * A list of header options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute header
         * @type {Array}
         * @default []
         */
        header: {
            value: []
        },

        /**
         * A list of footer options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute footer
         * @type {Array}
         * @default []
         */
        footer: {
            value: []
        },

        /**
         * A list of result formats options to be displayed in the widget
         * See {{#crossLink 'SearchResultWidgetWizard/OPTIONS:property'}}{{/crossLink}} property for the list of options available
         *
         * @attribute result formats
         * @type {Array}
         * @default []
         */
        resultFormats: {
            value: []
        },
        /**
         *  metadata selection refactoring
         *  array of objects containing selected metadata
         *  each obect has following propertes
         *  key - code of metadata attribute
         *  metadataFieldType - type of metadata attribute
         *  showLabel - value of showLabel checkbox
         *  maxLength - number of characters to be displayed
         *  formatsType - for formats metadata specify if they will be displayed as ICON or TEXT
         *
         * @type {Array}
         */
        selectedMetaDataFieldType: {
            value: [
                {
                    "key": "title",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": false
                },
                {
                    "key": "published_date",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "status",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "submission_deadline",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "type_of_contract",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "buyer",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "main_cpv",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": true
                },
                {
                    "key": "description",
                    "maxItems": 0,
                    "maxLength": 0,
                    "metadataFieldType": "TEXT",
                    "showLabel": false
                },
                {
                    "align": "left",
                    "key": "shareButton",
                    "maxItems": 0,
                    "maxLength": 0,
                    "showLabel": false
                }
            ]
        },

        selectedMetadata: {
            value: [
                "title",
                "description",
                "published_date",
                "submission_deadline",
                "status",
                "type_of_contract",
                "buyer",
                "estimated_contract_value",
                "main_cpv",
                "nuts"
            ]
        },

        layoutRows: {
            value: 5
        },

        metadataAppearanceList: {
            value: []
        },

        widgetAppearance: {
        },

    };

    Y.extend(PublicProcurementSelectedWidgetWizard, Y.BaseWidgetList, {

        setWizardType: function () {
            var instance = this;
            instance.set("widgetType", 9);
        },
        setLoadCalls: function () {
            var instance = this;
            instance.set("loadCalls", 1);
        },
        initWizard: function () {
            var instance = this,
                    host = this.get('host');
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general'),
                    instance.t('searchResult.appearance'),
                    instance.t('statistics.publications.details')
                ],
                children: [
                    instance.getGeneralSettings(),
                    instance.getAppearanceSettings(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                        if(instance.get('layoutColumns') && instance.get('layoutRows')) {
                            if ((instance.get('layoutColumns') * instance.get('layoutRows')) > 50 &&
                                Y.one(".message-to-show").hasClass('hidden')) {
                                Y.one(".message-to-show").removeClass('hidden');
                            } else {
                                Y.one(".message-to-show").addClass('hidden');
                            }
                        }
                        instance.validateWidget();
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();
            instance.initLayoutItem();

            new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + "_buttonRow",
                        children: instance.getButtonsBar()
                    })
                ]
            }).render(host);

            instance.fireLoadCallFinished();

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.convertLayoutStyleToJson();
                instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });

        },
        /**
         * This panel displays widget title and the selection of publications that will appear in the widget
         *
         * @method getPropertiesStep
         * @return {PanelElement} the panel with widget properties configuration
         */
        getGeneralSettings: function () {
            var instance = this,
                    host = instance.get('host'),
                    isEdit = instance.get('widgetId') > 0;
            var metadataOpt = instance.getMetadataTranslation();

            var step = new Y.HtmlElement({
                id: 'tab-1',
                cssClass: 'tab-pane active',
                children: [
                    new Y.PanelElement({
                        label: instance.t('publication.properties'),
                        children: [
                            new Y.InputElement({
                                label: instance.t('publication.name'),
                                name: FIELD_NAME,
                                modelInstance: instance,
                                placeholder: instance.t('baseWidgetList.name.placeholder'),
                                cssClass: 'widget-input',
                                required: true,
                                validateFunction: function () {
                                    instance.validateWidget();
                                }
                            }),
                            new Y.InputElement({
                                label: instance.t('publication.description'),
                                name: FIELD_DESCRIPTION,
                                placeholder: instance.t('baseWidgetList.description.placeholder'),
                                modelInstance: instance,
                                cssClass: 'widget-input'
                            }),
                            /**
                             * Language selection option. Automatic option or manual selection of language
                             */
                            instance.getLanguageSelector(),
                            instance.getShowOnlySelectedLanguagePublicationsSelector()
                        ]
                    }),
                    new Y.PanelElement({
                        label: instance.t('publication.publications'),
                        children: [
                            new Y.SelectedPublicationsElement({
                                id: 'selectedPublicationsSelector',
                                cssClass: 'selected-publications-css-class',
                                labels: {
                                    availablePublications: instance.t('publication.availablePublications'),
                                    publicationsTableHeader_no: instance.t('publication.table.no'),
                                    publicationsTableHeader_documentTitle: instance.t('publication.table.documentTitle'),
                                    publicationsTableHeader_format: instance.t('publication.table.format'),
                                    publicationsTableHeader_language: instance.t('publication.table.language'),
                                    addPublication: instance.t('publication.add'),
                                    addPermanentLink: instance.t('publication.addPermanentLink'),
                                    selectedPublications: instance.t('publication.selectedPublications'),
                                    sortBy: instance.t('publication.order'),
                                },
                                name: FIELD_SAVED_PUBLICATIONS,
                                fieldSortBy: FIELD_PUBLICATION_ORDER,
                                sortByCriteria: [
                                    {key: '', value: instance.t('publication.order.default')},
                                    {key: 'PUBLICATION_DATE', value: instance.t('baseWidgetList.orderBy.procurementDate')},
                                    {key: 'TITLE', value: instance.t('publication.order.title')}
                                ],
                                fieldCellarIds: FIELD_CELLAR_IDS,
                                fieldCustomOrder: isEdit ? FIELD_SELECTED_INFORMATION : undefined, // backward compatibility
                                fieldPermanentLinks: isEdit ? FIELD_PERMANENT_LINKS : undefined, // backward compatibility
                                modelInstance: instance,
                                getSavedPublicationsURL: Liferay.portal2012[instance.get('namespace') + "myPublicProcurementDocumentsUrl"],
                                getMissingPublicationsURL: Liferay.portal2012[instance.get('namespace') + "getPublicationsNames"] +
                                '&' + instance.get('namespace') + 'cellarIds=',
                                myPublicationsPageURL: Liferay.portal2012[instance.get('namespace') + "myPublicationsPageURL"]
                            })
                        ]
                    }),
                    /**
                     * Metadata selection, default metadata.
                     */
                    new Y.HtmlElement({
                        id: instance.get(ELEM_ATTR.NAMESPACE) + "metaselect",
                        wrapperCssClass: 'row',
                        children: [
                            new Y.MetadataEditInTableElement({
                                label: instance.t('baseWidgetList.displayedMetadata'),
                                modelInstance: instance,
                                name: FIELD_SELECTED_METADATA,
                                options: METADATA,
                                displayOrderButton: false
                            })]
                    }),
                    new Y.PanelElement({
                        label: instance.t('publication.targetPage'),
                        children: [
                            instance.getTargetPageStep()
                        ]
                    })
                ]
            });

            return step;
        },

        getStatisticsTable: function () {
            var instance = this, tab;
            var isEdit = instance.get('widgetId') > 0;

            var tableStatistics = [];

            tableStatistics.push(instance.getTableStatistics());

            if (isEdit) {
                tableStatistics.push(instance.getTableDetaliedStatistics());
            }

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: tableStatistics
                    }),
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        // label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        htmlContent: '<a  class="pull-right" href="' + Liferay.portal2012[instance.get('namespace') + "downloadStatisticsPubDetail"] + '">' + instance.t('statistics.download') + '</a>'
                    })
                ]
            });

            return tab;
        },

        getTableStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSelectedPub"],
                    data = [],
                    columns = [],
                    i,
                    len;
            var widgetElement;
            var isEdit = instance.get('widgetId') > 0;


            if (widgetList) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: parseInt(widgetElement.visits),
                        clicks: parseInt(widgetElement.clicksPerm + widgetElement.clicksSearch)
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            if (!isEdit) {
                table.set('rowsPerPage', 25);
                table.set('pageSizes', [10, 25, 50])
                table.set('paginatorLocation', ['footer']);
            }

            return table;
        },

        getTableDetaliedStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSelectedPub"],
                    data = [],
                    columns = [],
                    i, j,
                    len, lenJ;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement, detailsWidgetElement = [];


            if (widgetList) {
                for (i = 0, len = (widgetList.length ); i < len; i++) {
                    if (widgetList[i].publicationStatisticsDTOList) {
                        detailsWidgetElement = widgetList[i].publicationStatisticsDTOList;

                        for (j = 0, lenJ = detailsWidgetElement.length; j < lenJ; j++) {
                            widgetElement = detailsWidgetElement[j];
                            data.push({
                                publications: widgetElement.publication,
                                searchClicks: widgetElement.searchClicks,
                                noImpresions: widgetElement.noImpressions

                            });
                        }
                    }
                }
            }

            columns = [
                {
                    key: 'publications',
                    label: instance.t('statistics.table.publications'),
                    width: '60%',
                    className: 'numeric'
                },
                {
                    key: 'noImpresions',
                    width: '20%',
                    label: instance.t('statistics.table.impressions'),
                    sortable: true
                },
                {
                    key: 'searchClicks',
                    width: '20%',
                    label: instance.t('statistics.table.clicks'),
                    sortable: true
                }

            ];

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 25);
            table.set('pageSizes', [10, 25, 50])
            table.set('paginatorLocation', ['footer']);


            return table;
        },

        getAppearanceSettings: function () {
            var instance = this,
                    tab;

            var layout = instance.getLayoutStep();
            var basicConfiguration = null;
            var advancedConfiguration = null;

            /**
             * Basic config for simple Appearance
             */
            if (instance.get('widgetAppearance') != undefined && instance.get('widgetAppearance') != null) {
                basicConfiguration = instance.get('widgetAppearance');
            }

            /**
             * advanced config for simple Appearance
             */
            if (instance.get('metadataAppearanceList') != undefined && instance.get('metadataAppearanceList') != null) {
                advancedConfiguration = instance.get('metadataAppearanceList');
            }

            /**
             * Slide show edit configuration
             */
            if (instance.get('slideShowLayout') != undefined && instance.get('slideShowLayout') != null) {
                slideShowLayout = instance.getLayoutStyleStep(instance.get('slideShowLayout'));
            }
            else {
                slideShowLayout = instance.getLayoutStyleStep(null);
            }


            /**
             * Appearance settings tab configuration.
             * if parameters for getDisplayAppearence() doesn't exists, provide null as parameter.
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(basicConfiguration, advancedConfiguration, true, true);

            instance.after(FIELD_LAYOUT + "Change", function (e) {
                var instance = e.currentTarget;
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance.after(FIELD_SELECTED_METADATA + "Change", function (e) {
                var instance = e.currentTarget;
                // remove events
                instance._resetLayoutEvents();
                instance._layoutSet();
                instance._setLayoutMetadata();
            });

            instance._addDropDownEvents();
            instance._layoutSet(true);

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    new Y.HtmlElement({
                        label: instance.t('searchResult.header'),
                        cssClass: 'form-inline',
                        children: instance.getHeaderFooterOptionList(FIELD_HEADER)
                    }),
                    new Y.HtmlElement({
                        label: instance.t('searchResult.footer'),
                        cssClass: 'form-inline',
                        children: instance.getHeaderFooterOptionList(FIELD_FOOTER)
                    }),
                    layout,
                    slideShowLayout,
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });


            return tab;
        },

        getStatistics: function () {
            var instance = this,
                    step, i;

            step = new Y.PanelElement({
                id: 'tab-3',
                label: instance.t('publication.properties')
            })

            return step;
        },

        getButtonsBar: function () {
            var instance = this, toolBar = [];
            var isExistentWidget = (parseInt(instance.get('widgetId')) > 0);
            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' disabled' : ''),
                htmlContent: instance.t('baseWidgetList.save'),
                onClick: function (e) {
                    if (!instance.validateWidget()) {
                        return;
                    }
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertLayoutStyleToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doSaveWidget();
                }
            }));
            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right get-button' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.getCode'),
                onClick: function (e) {
                    instance.convertBasicAppearanceObjListToJson();
                    instance.convertLayoutStyleToJson();
                    instance.convertBasicAppearanceMetaObjListToJson(instance.getAdvancedAppearenceMetaDataObjectList());
                    instance.doGetWidget();
                }
            }));

            toolBar.push(new Y.HtmlElement({
                element: 'button',
                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' hidden' : ''),
                htmlContent: instance.t('baseWidgetList.cancel'),
                onClick: function (e) {
                    instance.doReturnToMyWidgets();
                }
            }));

            return toolBar;
        },

        validateWidget: function () {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });

            // validate the product rows*columns <50
            if(instance.get('layoutColumns') && instance.get('layoutRows') && isValidated) {
                if ((instance.get('layoutColumns') * instance.get('layoutRows')) > 50) {
                    isValidated = false;
                }
            }

            if (isValidated) {
                actionButtons.removeClass('disabled');
                actionButtons.set('disabled',false)
            }
            else {
                actionButtons.addClass('disabled');
                actionButtons.set('disabled',true)
            }
            return isValidated;
        }
    });

    Y.namespace('Plugin').PublicProcurementSelectedWidgetWizard = PublicProcurementSelectedWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'baseWidgetList'
    ]
});
/**
 * This module generates the search box widget wizard
 *
 * @module organizationWidgetWizard
 * @requires wizardTools
 */
YUI.add('organizationWidgetWizard', function (Y) {
    var
            /**
             * Static constant to refer field 'name'
             *
             * @property FIELD_NAME
             * @type String
             * @static
             * @final
             */
            FIELD_NAME = 'name',
            /**
             * Static constant to refer field 'selectedOrganization'
             *
             * @property FIELD_NAME
             * @type String
             * @static
             * @final
             */
            FIELD_SELECTED_ORGANIZATION = 'selectedOrganization',

            BASE_ORGANIZATION = 'EURUN/EURUN',
            //BASE_ORGANIZATION = 'PUBL/PUBL',

            FIELD_DESCRIPTION = 'description';


    /**
     * Generates the dom and dom events for search box wizard
     *
     * @param cfg
     * @constructor
     * @class OrganizationWidgetWizard
     * @extends AbstractWizard
     */
    function OrganizationWidgetWizard(cfg) {
        OrganizationWidgetWizard.superclass.constructor.apply(this, arguments);
    }

    OrganizationWidgetWizard.NAME = 'OrganizationWidgetWizard';
    OrganizationWidgetWizard.NS = 'OrganizationWidgetWizard';

    OrganizationWidgetWizard.ATTRS = {

        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },

        /**
         * Keeps the target page of the search box
         *
         * @attribute targetPage
         * @type String
         * @default {}
         */
        targetPage: {
            value: ''
        },

        /**
         * Appearance tab
         */
        setAppearanceTabs: null,

        /**
         * Array of objects with the following structure
         *      {
         *          type: 'CriteriaType',
         *          visibleToUsers: true,
         *          criteriaMandatory: true,
         *          defaultValue: '',
         *          cssClass: '',
         *          weight: ''
         *      }
         *
         * @attribute criteria
         * @type Array
         * @default []
         */
        criteria: {
            value: []
        },
        selectedEntity: {
            value: ''
        },
        accessibleEntityLevels: {
            values: ''
        },
        canClickOnPeople: {
            value: false
        },
        collapseExpandEntities: {
            value: false
        },
        showTheBreadCrump: {
            value: false
        }
    };
    Y.extend(OrganizationWidgetWizard, Y.BaseWidgetList, {
        selectOrganizationWidgetInstance: null,
        classifications: {},
        initWizard: function () {
            var instance = this,
                    host = this.get('host'),
                    isEdit = instance.get('widgetId') > 0;
            instance.set('widgetType', '6');
            var firstLoad = true;

            var renderClassifications = function () {
                var renderedCheckboxes = "<ul>";
                for (var classification in instance.classifications) {
                    if (classification.length > 0) {
                        var checkedHtml = "";
                        var label = instance.classifications[classification].label;
                        if (instance.classifications[classification].checked) {
                            checkedHtml = "checked='checked'";
                        }

                        renderedCheckboxes += "<li><input type='checkbox' value='" + classification + "' title='" + label + "' " + checkedHtml + " />" + label + "</li>";
                    }
                }

                renderedCheckboxes += "</ul>";

                Y.one('#' + instance.get("namespace") + "accessibleLevelsChecklistContainer").setHTML(renderedCheckboxes);
            }

            var treeLoadEventHandler = Y.on(Y.SelectOrganizationWidget.TREE_UPDATED_EVENT, function (e) {
                if (isEdit && firstLoad) {
                    firstLoad = false;
                    return;
                }
                firstLoad = false;
                //we need to parse the classifications and the labels in order to build the options
                e.options.forEach(function (element) {
                    if (typeof instance.classifications[element.classification] == "undefined") {
                        instance.classifications[element.classification] = {
                            label: element.classification_label,
                            checked: false
                        }
                    }
                });

                //updating the html element
                renderClassifications([]);
            });

            instance._addDropDownEvents();

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general')
                    , instance.t('searchResult.appearance')
                ],
                children: [
                    instance.getGeneralSettings()
                    , instance.getAppearanceSettings()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();

            new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + "_buttonRow",
                        children: [
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!instance.get('widgetId') > 0 ? ' disabled' : ''),
                                htmlContent: instance.t('searchBox.save'),
                                onClick: function (e) {
                                    instance.convertBasicAppearanceObjListToJson();
                                    instance.convertSpecificFieldsToJson();
                                    instance.doSaveWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!instance.get('widgetId') > 0 ? ' disabled' : ''),
                                htmlContent: instance.t('searchBox.getCode'),
                                onClick: function (e) {
                                    instance.convertBasicAppearanceObjListToJson();
                                    instance.convertSpecificFieldsToJson();
                                    instance.doGetWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!instance.get('widgetId') > 0 ? ' hidden' : ''),
                                htmlContent: instance.t('baseWidgetList.cancel'),
                                onClick: function (e) {
                                    instance.doReturnToMyWidgets();
                                }
                            })
                        ]
                    })
                ]
            }).render(host);

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.convertSpecificFieldsToJson();
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });
        },

        convertSpecificFieldsToJson: function () {
            var instance = this;
            var selectedElement = instance._getSelectOrganizationWidget().getSelectedElement();
            // instance.set("selectedEntity", selectedElement.path.join("||"));
            var selectedEntities = [];
            if(selectedElement != null){
                for (i = 0; i < selectedElement.path.length; i++) {
                    var selectedEntity = {};
                    selectedEntity["value"] = selectedElement.path[i];
                    selectedEntities.push(selectedEntity);
                }
            }
            if(selectedEntities.length>0){
                //ODR-971 - EU WhoIsWho: detail page: button to create a widget does not work as expected
                // when user enter in edit mode nothing is selected in the tree and it will lead to an exception
                instance.set("selectedEntity", Y.JSON.stringify(selectedEntities));
            }

            var accesibleLevels = [];
            //converting the accesible levels
            Y.all('.accessibleLevelsChecklistContainer input').each(function (element) {
                var accesibleLevel = {};
                accesibleLevel["val"] = element.val();
                accesibleLevel["checked"] = (element.attr('checked') ? "true" : "false");
                accesibleLevel["title"] = element.attr('title');
                accesibleLevels.push(accesibleLevel);
                // accesibleLevels += element.val() + '||' + (element.attr('checked') ? "true" : "false") + "||" + element.attr('title') + "||";
            });

            instance.set("accessibleEntityLevels", Y.JSON.stringify(accesibleLevels));
        },

        /**
         * Retruns DOM objects for the general tab - the widgets components
         * @returns {Y.PanelElement} - YUI object that neeeds to be rendered
         */
        getGeneralSettings: function () {
            var instance = this;
            var returnOBJ;

            returnOBJ = new Y.PanelElement({
                wrapperCssClass: 'tab-pane active',
                id: 'tab-1',
                children: [
                    new Y.InputElement({
                        label: instance.t('searchBox.name'),
                        name: FIELD_NAME,
                        modelInstance: instance,
                        placeholder: instance.t('baseWidgetList.name.placeholder'),
                        cssClass: 'widget-input',
                        required: true,
                        validateFunction: function () {
                            instance.validateWidget(true)
                        }
                    }),
                    new Y.InputElement({
                        label: instance.t('searchBox.description'),
                        name: FIELD_DESCRIPTION,
                        placeholder: instance.t('baseWidgetList.description.placeholder'),
                        modelInstance: instance,
                        cssClass: 'widget-input'
                    }),
                    instance.getLanguageSelector(),
                    instance._createEntitySelectionElement(),
                    instance._createOptionsElement()
                ]
            });

            return returnOBJ;
        },

        /**
         * Retunrns the DOM objects for the Appearance Tab
         * @returns {Y.PanelElement} - YUI elements that need to be rendered
         */
        getAppearanceSettings: function () {
            var instance = this;
            var tab;

            var basicConfiguration = null;
            var advancedConfiguration = null;

            if (instance.get('widgetAppearance') != undefined && instance.get('widgetAppearance') != null) {
                basicConfiguration = instance.get('widgetAppearance');
            }

            /**
             * if parameters for getDisplayAppearence() doesn't exists, provide null as parameter.             *
             * @type {Y.TabView}
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(basicConfiguration, advancedConfiguration, true, false);


            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });


            return tab;
        },

        destructWizard: function () {
            this._getSelectOrganizationWidget().destructWizard();
            this.selectOrganizationWidgetInstance = null;
        },
        /**
         * Returns the DOM structure for options selection
         *
         * @method _createOptionsElement
         * @return {HtmlElement}
         * @private
         */
        _createOptionsElement: function () {
            var instance = this,
                    children = [], i;

            var optionsContainerId = instance.get('namespace') + "optionsContainer";
            return new Y.PanelElement({
                label: instance.t('organization.options'),
                children: [
                    new Y.HtmlElement({
                        element: "div",
                        id: optionsContainerId,
                        children: [
                            instance._getAccessibleLevelsOption(),
                            new Y.CheckboxElement({
                                label: instance.t('organization.collapseExpandEntities'),
                                wrapperCssClass: 'col-md-12 check',
                                checked: (instance.getAttrs().collapseExpandEntities ? true : false),
                                modelInstance: instance,
                                //id: FIELD_SHARE_THIS,
                                onClick: function () {
                                    if (!instance.getAttrs().collapseExpandEntities) {
                                        instance.set("collapseExpandEntities", true);
                                    }
                                    else {
                                        instance.set("collapseExpandEntities", false);
                                    }
                                }
                            }),
                            new Y.CheckboxElement({
                                label: instance.t('organization.showTheBreadCrump'),
                                wrapperCssClass: 'col-md-12 check',
                                checked: (instance.getAttrs().showTheBreadCrump ? true : false),
                                modelInstance: instance,
                                //id: FIELD_SHARE_THIS,
                                onClick: function () {
                                    if (!instance.getAttrs().showTheBreadCrump) {
                                        instance.set("showTheBreadCrump", true);
                                    }
                                    else {
                                        instance.set("showTheBreadCrump", false);
                                    }
                                }
                            }),
                            new Y.CheckboxElement({
                                label: instance.t('organization.canClickOnPeople'),
                                wrapperCssClass: 'col-md-12 check',
                                checked: (instance.getAttrs().canClickOnPeople ? true : false),
                                modelInstance: instance,
                                //id: FIELD_SHARE_THIS,
                                onClick: function () {
                                    if (!instance.getAttrs().canClickOnPeople) {
                                        instance.set("canClickOnPeople", true);
                                    }
                                    else {
                                        instance.set("canClickOnPeople", false);
                                    }
                                }
                            })
                        ]
                    })
                ]
            });
        },
        _getAccessibleLevelsOption: function () {
            var instance = this;
            var existingLevels = instance.get('accessibleEntityLevels');
            var children = [];
            if (existingLevels) {
                var splitedLevels = existingLevels;
                if (typeof splitedLevels === 'string' || splitedLevels instanceof String) {
                    splitedLevels = JSON.parse(existingLevels);
                }
                for (var iLevel = 0; iLevel < splitedLevels.length; iLevel++) {
                    var value = splitedLevels[iLevel].val;
                    if (value.length > 0) {
                        var checked = splitedLevels[iLevel].checked === "true";
                        var label = splitedLevels[iLevel].title;
                        instance.classifications[value] = {
                            label: label,
                            checked: checked
                        };
                        children[children.length] = new Y.HtmlElement({
                            element: "li",
                            children: [
                                new Y.CheckboxElement({
                                    title: label,
                                    checked: checked,
                                    value: value
                                }),
                                new Y.HtmlElement({
                                    element: "span",
                                    htmlContent: label
                                })
                            ]
                        });
                    }
                }
            }

            return new Y.HtmlElement({
                element: "div",
                id: instance.get('namespace') + "accessibleLevelsContainer",
                htmlContent: instance.t("organization.accessibleLevels"),
                children: [
                    new Y.HtmlElement({
                        element: "div",
                        cssClass: "accessibleLevelsChecklistContainer",
                        id: instance.get('namespace') + "accessibleLevelsChecklistContainer",
                        children: [
                            new Y.HtmlElement({
                                element: "ul",
                                children: children
                            })
                        ]
                    })
                ]
            })
        },
        /**
         * Returns the DOM structure for entity selection
         *
         * @method _createEntitySelectionElement
         * @return {HtmlElement}
         * @private
         */
        _createEntitySelectionElement: function () {
            var instance = this,
                    children = [], i;
            var sublevelsContainerId = instance.get('namespace') + "sublevelsContainer";
            var currentValue = instance.get("selectedEntity");
            return new Y.PanelElement({
                label: instance.t('organization.entity'),
                children: [
                    new Y.HtmlElement({
                        element: "div",
                        id: sublevelsContainerId,
                        children: [
                            instance._getSelectOrganizationWidget(currentValue)
                        ]
                    })
                ]
            });
        },

        _getSelectOrganizationWidget: function (currentValue) {
            var instance = this;
            if (this.selectOrganizationWidgetInstance == null) {
                this.selectOrganizationWidgetInstance = new Y.SelectOrganizationWidget({
                    id: 'organizationSelector',
                    currentValue: currentValue,
                    baseOrganization: BASE_ORGANIZATION,
                    locale: Liferay.portal2012[instance.get('namespace') + "locale"],
                    cssClass: 'selected-publications-css-class',
                    labels: {
                        availablePublications: instance.t('publication.availablePublications')
                    },
                    name: FIELD_SELECTED_ORGANIZATION,
                    validator: function () {
                        instance.validateWidget();
                    }
                });
            }

            return this.selectOrganizationWidgetInstance;
        },
        validateWidget: function (name) {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate selected organization */
            var selectedElement = instance._getSelectOrganizationWidget().getSelectedElement();
            if (selectedElement == null && !name) {
                isValidated = false;
            }
            else {
                //updating the levels of the entity that should be accessible

            }

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });


            if (isValidated) {
                actionButtons.removeClass('disabled');
                actionButtons.set('disabled',false)
            }
            else {
                actionButtons.addClass('disabled');
                actionButtons.set('disabled',true)
            }
        },

        /**
         * Returns an array of available languages and caches the result in
         * {{#crossLink 'OrganizationWidgetWizard/CRITERIA_AVAILABLE_LANGUAGES:property'}}{{/crossLink}} property
         *
         * @method _getAvailableLanguages
         * @return {Array} of objects of type {key : 'key', value: 'value'}
         * @private
         */
        _getAvailableLanguages: function () {
            var instance = this;
            if (!CRITERIA_AVAILABLE_LANGUAGES) {
                CRITERIA_AVAILABLE_LANGUAGES = Liferay.portal2012[instance.get('namespace') + "criteriaAvailableLanguages"];
            }

            return CRITERIA_AVAILABLE_LANGUAGES;
        }
    });

    Y.namespace('Plugin').OrganizationWidgetWizard = OrganizationWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'node',
        'base-build',
        'plugin',
        'classnamemanager',
        'attribute-base',
        'io-base',
        'history-hash',
        'wizardTools',
        'formWidget',
        'dd-constrain',
        'dd-proxy',
        'dd-drop',
        'autocomplete',
        'datatype',
        'baseWidgetList',
        'selectOrganizationWidget'
    ]
});
/**
 * Created by andreit on 11/1/2016.
 */

YUI.add('publicationStatisticsWidgetWizard', function (Y) {

    var FIELD_ID='widgetId',
        FIELD_TYPE='widgetType',
        FIELD_NAME='widgetName',
        FIELD_AUTHOR='widgetAuthor',
        FIELD_NO_IMPRESSIONS='widgetNoImpressions',
        ELEM_ATTR = {
            CHECKBOX_STATUS: 'checked',
            VALUE:'value',
            NAMESPACE:'namespace'
        }



    /**
     * Generates the dom and dom events for search result widget wizard
     *
     * @param cfg
     * @constructor
     * @class SearchResultWidgetWizard
     * @extends BaseWidgetList
     */

    function PublicationStatisticsWidgetWizard(cfg) {
        PublicationStatisticsWidgetWizard.superclass.constructor.apply(this, arguments);
        this.initSavedObjects(cfg);
    }


    PublicationStatisticsWidgetWizard.NAME = 'PublicationStatisticsWidgetWizard';
    PublicationStatisticsWidgetWizard.NS = 'PublicationStatisticsWidgetWizard';

    PublicationStatisticsWidgetWizard.ATTRS = {
        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value:''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value:''
        },
        /**
         * Keeps the source for the results. Can be one of 'widget' or 'source'.
         * If the source is 'widget', then the query will be taken from the parent URL and be passed to the server to display the results.
         *
         * @attribute source
         * @type {String}
         * @default ''
         */
        source: {
            value: " "
        }

    }

    Y.extend(PublicationStatisticsWidgetWizard, Y.BaseWidgetList, {

        initWizard: function () {
            var instance = this, host = this.get('host');

            new Y.TabPanelElement({
                label: [instance.t('statistics.report'),
                        instance.t('statistics.selected.publication'),
                        instance.t('statistics.search.results'),
                        instance.t('statistics.publications.details'),
                        instance.t('statistics.search.form')
                ],
                children: [
                    instance.getAdminStatistics(),
                    instance.getSelectedPubStatistics(),
                    instance.getSearchResultStatistics(),
                    instance.getPublicationDetailsStatics(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function() {
                    instance.getWidgetStatistics();
                }
            }).render(host);


            instance.attachPreviewPanel(host, function() {

            },function(){
                instance.clearCache();
            });

        },

        getAdminStatistics: function() {
            var instance = this, tab;

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane active',
                id:'tab-1',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.admin.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: [
                            instance.getTableStatistics()
                        ]
                    })

                ]

            });

            return tab;
        },

        getSelectedPubStatistics: function() {
            var instance = this, tab;

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id:'tab-2',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.publication'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: [
                            instance.getTableStatistics()
                        ]
                    })
                ]
            });

            return tab;
        },

        getSearchResultStatistics: function() {
            var instance = this, tab;

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id:'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.search.results'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: [
                            instance.getTableStatistics()
                        ]
                    })
                ]
            });

            return tab;
        },

        getPublicationDetailsStatics: function() {
            var instance = this, tab;

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id:'tab-4',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.publication.detail'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: [
                            instance.getTableStatistics()
                        ]
                    })
                ]
            });

            return tab;
        },

        getStatisticsTable: function() {
            var instance = this, tab;

            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id:'tab-5',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: [
                            instance.getTableStatistics()
                        ]
                    })
                ]
            });

            return tab;
        },

        getTableElement: function(){
            var instance = this, tableElem;

            tableElem = new Y.TableElement({
                label: instance.t('searchResult.description'),
                name: FIELD_NAME,
                placeholder: instance.t('baseWidgetList.description.placeholder'),
                modelInstance: instance,
                tableSummary: "Test table",
                tableCaption: "Statistics",
                cssClass:'widget-table',
                tableColumns: ["id", "name", "price"],
                tableDate: [
                    { id: "ga_3475", name: "gadget",   price: "$6.99" },
                    { id: "sp_9980", name: "sprocket", price: "$3.75" },
                    { id: "wi_0650", name: "widget",   price: "$4.25" }
                ]
            })

            return tableElem;

        },

        getTableStatistics: function() {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsList"],
                data = [],
                columns = [],
                i,
                len;
            var widgetElement;


            if (widgetList) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: widgetElement.visits,
                        clicks: widgetElement.clicks
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 20);
            table.set('pageSizes', [10, 20, 50])
            table.set('paginatorLocation', ['footer']);

            return table;
        }

    });

    Y.namespace('Plugin').PublicationStatisticsWidgetWizard = PublicationStatisticsWidgetWizard;


}, 'portalop-2014.05.28-17-20', {
    requires: [
        'baseWidgetList',
        'aui-tabview',
        'tabview'
    ]
});
/**
 * This module generates the public procurement search form widget
 *
 * @module publicProcurementSearchBoxWidgetWizard
 * @requires wizardTools
 */
YUI.add('publicProcurementSearchBoxWidgetWizard', function (Y) {
    var
        /**
         * Static constant to refer field 'name'
         *
         * @property FIELD_NAME
         * @type String
         * @static
         * @final
         */
        FIELD_NAME = 'name',
        FIELD_DESCRIPTION = 'description',

        /**
         * Static constant to refer field 'resultsPage'
         *
         * @property FIELD_RESULTS_PAGE
         * @type String
         * @static
         * @final
         */
        FIELD_RESULTS_PAGE = 'resultsPage',

        /**
         * Static constant to refer field 'targetPage'
         *
         * @property FIELD_TARGET_PAGE
         * @type String
         * @static
         * @final
         */
        FIELD_TARGET_PAGE = 'targetPage',

        /**
         * Static constant to refer field 'criteria'
         *
         * @property FIELD_CRITERIA
         * @type String
         * @static
         * @final
         */
        FIELD_CRITERIA = 'criteria',

        /**
         * Defines the value that specifies that the search is redirected to eu law and publications website
         *
         * @property RESULTS_PAGE_EU_LAW
         * @type {string}
         * @static
         * @final
         */
        RESULTS_PAGE_EU_LAW = 'a',

        /**
         * Defines the value that specifies that the search is redirected to the page specified by {{#crossLink 'PublicProcurementSearchBoxWidgetWizard/targetPage:attribute'}}{{/crossLink}}
         *
         * @property RESULTS_PAGE_OWN
         * @type {string}
         * @static
         * @final
         */
        RESULTS_PAGE_OWN = 'b',

        /**
         * Defines text criteria type
         *
         * @property CRITERIA_TEXT
         * @type {string}
         * @static
         * @final
         */
        CRITERIA_TEXT = 'text',

        /**
         * Defines CPV criteria type
         *
         * @property CRITERIA_CPV
         * @type {string}
         * @static
         * @final
         */
        CRITERIA_CPV = 'cpv',

        /**
         * Defines NUTS criteria type
         *
         * @property CRITERIA_NUTS
         * @type {string}
         * @static
         * @final
         */
        CRITERIA_NUTS = 'nuts',

        /**
         * Defines buyer criteria type
         *
         * @property CRITERIA_BUYER
         * @type {string}
         * @static
         * @final
         */
        CRITERIA_BUYER = 'buyer',

        /**
         * Defines company awarded contract criteria type
         *
         * @property CRITERIA_COMPANIES_AWARDED_CONTRACTS
         * @type {string}
         * @static
         * @final
         */
        CRITERIA_COMPANIES_AWARDED_CONTRACTS = 'companiesAwardedContracts',

        /**
         * Defines publicationYear criteria type
         *
         * @property CRITERIA_YEAR
         * @type {string}
         * @static
         * @final
         */
        CRITERIA_YEAR = 'publicationYear',

        /**
         * Defines status criteria type
         *
         * @property CRITERIA_STATUS
         * @type {string}
         * @static
         * @final
         */
        CRITERIA_STATUS = 'status',

        /**
         * Keeps dd subscription so it will be removed when plugin is unloaded
         *
         * @property SUBSCRIPTION_DD_OVER
         * @type {string}
         * @static
         */
        SUBSCRIPTION_DD_OVER,

        /**
         * Keeps dd subscription so it will be removed when plugin is unloaded
         *
         * @property SUBSCRIPTION_DD_DRAG
         * @type {string}
         * @static
         */
        SUBSCRIPTION_DD_DRAG,

        /**
         * Keeps dd subscription so it will be removed when plugin is unloaded
         *
         * @property SUBSCRIPTION_DD_START
         * @type {string}
         * @static
         */
        SUBSCRIPTION_DD_START,

        /**
         * Keeps dd subscription so it will be removed when plugin is unloaded
         *
         * @property SUBSCRIPTION_DD_END
         * @type {string}
         * @static
         */
        SUBSCRIPTION_DD_END,

        /**
         * Keeps dd subscription so it will be removed when plugin is unloaded
         *
         * @property SUBSCRIPTION_DD_DROP_HIT
         * @type {string}
         * @static
         */
        SUBSCRIPTION_DD_DROP_HIT,

        /**
         * Keeps a list of available criterias for search
         *
         * @property AVAILABLE_CRITERIA
         * @type {string}
         * @static
         * @final
         */
        AVAILABLE_CRITERIA = [
            {
                label: 'textSearch',
                type: CRITERIA_TEXT,
                defaultVisible: true,
                defaultMandatory: true
            },
            {
                label: 'cpv',
                type: CRITERIA_CPV,
                defaultVisible: true,
                defaultMandatory: false,
                valuesCallback: '_getValuesCPV',
                useAjax: true
            },
            {
                label: 'nuts',
                type: CRITERIA_NUTS,
                defaultVisible: true,
                defaultMandatory: false,
                valuesCallback: '_getValuesNUTS',
                useAjax: true
            },
            {
                label: 'buyer',
                type: CRITERIA_BUYER,
                defaultVisible: true,
                defaultMandatory: false
            },
            {
                label: 'companiesAwardedContracts',
                type: CRITERIA_COMPANIES_AWARDED_CONTRACTS,
                defaultVisible: true,
                defaultMandatory: false
            },
            {
                label: 'publicationYear',
                type: CRITERIA_YEAR,
                defaultVisible: true,
                defaultMandatory: false
            },
            {
                label: 'status',
                type: CRITERIA_STATUS,
                defaultVisible: true,
                defaultMandatory: false,
                valuesCallback: '_getAvailableStatus',
                multiple: true
            },
        ],

        /**
         * Caches the available status codes
         *
         * @property CRITERIA_AVAILABLE_STATUS
         * @type {string}
         * @static
         */
        CRITERIA_AVAILABLE_STATUS,

        /**
         * Static property to check if the dragged element is dragged up
         *
         * @property goingUp
         * @type {boolean}
         * @static
         */
        goingUp = false,

        /**
         * Static property to check Y position of dragged element
         *
         * @property lastY
         * @type {int}
         * @static
         */
        lastY = 0;

    /**
     * Generates the dom and dom events for search box wizard
     *
     * @param cfg
     * @constructor
     * @class PublicProcurementSearchBoxWidgetWizard
     * @extends AbstractWizard
     */
    function PublicProcurementSearchBoxWidgetWizard(cfg) {
        PublicProcurementSearchBoxWidgetWizard.superclass.constructor.apply(this, arguments);
    }

    PublicProcurementSearchBoxWidgetWizard.NAME = 'PublicProcurementSearchBoxWidgetWizard';
    PublicProcurementSearchBoxWidgetWizard.NS = 'PublicProcurementSearchBoxWidgetWizard';

    PublicProcurementSearchBoxWidgetWizard.ATTRS = {

        /**
         * Keeps the widget name
         *
         * @attribute name
         * @type String
         * @default ''
         */
        name: {
            value: ''
        },

        /**
         * Keeps the widget description
         *
         * @attribute description
         * @type String
         * @default ''
         */
        description: {
            value: ''
        },

        /**
         * Keeps the selected option by the user, referring to form action url
         *
         * @attribute resultsPage
         * @type String
         * @default 'a'
         */
        resultsPage: {
            value: RESULTS_PAGE_EU_LAW
        },

        /**
         * Keeps the target page of the search box
         *
         * @attribute targetPage
         * @type String
         * @default {}
         */
        targetPage: {
            value: ''
        },

        /**
         * Appearance tab
         */
        setAppearanceTabs: null,

        /**
         * Array of objects with the following structure
         *      {
         *          type: 'CriteriaType',
         *          visibleToUsers: true,
         *          criteriaMandatory: true,
         *          defaultValue: '',
         *          cssClass: '',
         *          weight: ''
         *      }
         *
         * @attribute criteria
         * @type Array
         * @default []
         */
        criteria: {
            value: []
        }
    };
    Y.extend(PublicProcurementSearchBoxWidgetWizard, Y.BaseWidgetList, {
        initWizard: function () {
            var instance = this,
                host = this.get('host'),
                isEdit = instance.get('widgetId') > 0;
            instance.set('widgetType', '7');
            instance._addDropDownEvents();
            var templatesButtonRow = Y.one('#' + instance.get('namespace') + '_templatesButtonRow');
            if (templatesButtonRow === null || templatesButtonRow === undefined) {
                new Y.HtmlElement({
                    cssClass: '',
                    children: [
                        new Y.HtmlElement({
                            cssClass: 'button-row',
                            id: instance.get('namespace') + '_templatesButtonRow',
                            children: instance.getTemplatesButtonBar()
                        })
                    ]
                }).render(host);
            }

            new Y.TabPanelElement({
                label: [instance.t('searchResult.general'),
                    instance.t('searchResult.appearance'),
                    instance.t('statistics.search.form')
                ],
                children: [
                    instance.getGeneralSettings(),
                    instance.getAppearanceSettings(),
                    instance.getStatisticsTable()
                ],
                onTabChange: function (e) {
                    var currentTab = e.currentTarget;
                    if (currentTab) {
                        var tabIndex = currentTab.ancestor().all('li').indexOf(currentTab);
                        instance.displayPreviewNode(tabIndex == 1);
                    }
                }
            }).render(host);

            instance.setAppearanceTabs.render(Y.one("#sr-widget-inner"));
            instance.advancedToBasicAppearanceCSS();

            var isExistentWidget = (parseInt(instance.get('widgetId')) > 0);
            new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'button-row',
                        id: instance.get('namespace') + "_buttonRow",
                        children: [
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' disabled' : ''),
                                htmlContent: instance.t('searchBox.save'),
                                onClick: function (e) {
                                    if (!instance.validateWidget()) {
                                        return;
                                    }
                                    instance.convertBasicAppearanceObjListToJson();
                                    instance.doSaveWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right get-button' + (!isExistentWidget ? ' hidden' : ''),
                                htmlContent: instance.t('searchBox.getCode'),
                                onClick: function (e) {
                                    instance.convertBasicAppearanceObjListToJson();
                                    instance.doGetWidget()
                                }
                            }),
                            new Y.HtmlElement({
                                element: 'button',
                                cssClass: 'btn btn-primary pull-right' + (!isExistentWidget ? ' hidden' : ''),
                                htmlContent: instance.t('baseWidgetList.cancel'),
                                onClick: function (e) {
                                    instance.doReturnToMyWidgets();
                                }
                            })
                        ]
                    })
                ]
            }).render(host);

            instance.attachPreviewPanel(host, function () {
                instance.convertBasicAppearanceObjListToJson();
                instance.doPreviewWidget();
            }, function () {
                instance.clearCache();
            });

            var criteriaList = host.one('.criteria-list'),
                id = criteriaList.get('id');
            var lis = host.one('.criteria-list').all('.available-criteria');
            lis.each(function (v, k) {
                var dd = new Y.DD.Drag({
                    node: v,
                    target: {
                        padding: '0 0 0 20'
                    }
                }).plug(Y.Plugin.DDProxy, {
                    moveOnEnd: false
                }).plug(Y.Plugin.DDConstrained, {
                    constrain2node: '#' + id
                });
            });

            //Create simple targets for the 2 lists.
            new Y.DD.Drop({
                node: criteriaList
            });
        },

        /**
         * Retruns DOM objects for the general tab - the widgets components
         * @returns {Y.PanelElement} - YUI object that neeeds to be rendered
         */
        getGeneralSettings: function () {
            var instance = this;
            var returnOBJ;

            returnOBJ = new Y.PanelElement({
                wrapperCssClass: 'tab-pane active',
                id: 'tab-1',
                children: [
                    new Y.InputElement({
                        label: instance.t('searchBox.name'),
                        name: FIELD_NAME,
                        modelInstance: instance,
                        placeholder: instance.t('baseWidgetList.name.placeholder'),
                        cssClass: 'widget-input',
                        required: true,
                        validateFunction: function () {
                            instance.validateWidget()
                        }
                    }),
                    new Y.InputElement({
                        label: instance.t('searchBox.description'),
                        name: FIELD_DESCRIPTION,
                        placeholder: instance.t('baseWidgetList.description.placeholder'),
                        modelInstance: instance,
                        cssClass: 'widget-input'
                    }),
                    instance.getLanguageSelector(),
                    instance._createCriteriaElements(),
                    new Y.HtmlElement({
                        label: instance.t('searchBox.resultsPage'),
                        children: [
                            new Y.RadioElement({
                                label: instance.t('searchBox.useTheResultsPageOfEuLawAndPublicationsWebsite'),
                                value: RESULTS_PAGE_EU_LAW,
                                modelInstance: instance,
                                name: FIELD_RESULTS_PAGE
                            }),
                            new Y.RadioElement({
                                label: instance.t('searchBox.ownResultsPage'),
                                value: RESULTS_PAGE_OWN,
                                modelInstance: instance,
                                name: FIELD_RESULTS_PAGE
                            })
                        ]
                    }),
                    new Y.InputElement({
                        label: instance.t('searchBox.targetPage'),
                        name: FIELD_TARGET_PAGE,
                        modelInstance: instance
                    })
                ]
            });

            return returnOBJ;
        },

        /**
         * Retunrns the DOM objects for the Appearance Tab
         * @returns {Y.PanelElement} - YUI elements that need to be rendered
         */
        getAppearanceSettings: function () {
            var instance = this;
            var tab;

            var basicConfiguration = null;
            var advancedConfiguration = null;

            if (instance.get('widgetAppearance') != undefined && instance.get('widgetAppearance') != null) {
                basicConfiguration = instance.get('widgetAppearance');
            }

            /**
             * if parameters for getDisplayAppearence() doesn't exists, provide null as parameter.             *
             * @type {Y.TabView}
             */
            instance.setAppearanceTabs = instance.getDisplayAppearence(basicConfiguration, advancedConfiguration, true, false);


            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-2',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner',
                        label: 'Set appearance',
                        wrapperCssClass: 'widget-display-options col-md-12'
                    })
                ]
            });


            return tab;
        },

        getStatisticsTable: function () {
            var instance = this, tab;
            var isEdit = instance.get('widgetId') > 0;

            var tableStatistics = [];

            tableStatistics.push(instance.getTableStatistics());

            if (isEdit) {
                tableStatistics.push(instance.getTableDetaliedStatistics());
            }


            tab = new Y.PanelElement({
                wrapperCssClass: 'tab-pane',
                id: 'tab-3',
                children: [
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        children: tableStatistics
                    }),
                    new Y.HtmlElement({
                        id: 'sr-widget-inner2',
                        // label: instance.t('statistics.label.search.report'),
                        wrapperCssClass: 'widget-display-statistics col-md-12 sr-widget-inner',
                        cssClass: 'col-md-12',
                        htmlContent: '<a class="pull-right" href="' + Liferay.portal2012[instance.get('namespace') + "downloadStatisticsSearchForm"] + '">' + instance.t('statistics.download') + '</a>'
                    })
                ]
            });

            return tab;
        },

        getTableStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSearchForm"],
                data = [],
                columns = [],
                i,
                len;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement;

            if (widgetList) {
                for (i = 0, len = widgetList.length; i < len; i++) {
                    widgetElement = widgetList[i];
                    data.push({
                        id: widgetElement.widgetID,
                        widgetType: widgetElement.widgetType,
                        widgetName: widgetElement.widgetName,
                        creator: widgetElement.userId,
                        impressionsNo: widgetElement.noImpressions,
                        visits: parseInt(widgetElement.visits),
                        clicks: parseInt(widgetElement.clicksPerm + widgetElement.clicksSearch)
                    });
                }
            }

            columns = [
                {
                    key: 'id',
                    label: instance.t('statistics.table.id'),
                    width: '8.33%',
                    className: 'numeric'
                },
                {
                    key: 'widgetType',
                    width: '8.33%',
                    label: instance.t('statistics.table.type'),
                    sortable: true
                },
                {
                    key: 'widgetName',
                    label: instance.t('statistics.table.name'),
                    width: '50%'
                },
                {
                    key: 'creator',
                    label: instance.t('statistics.table.creator'),
                    width: '8.33%'
                },
                {
                    key: 'impressionsNo',
                    label: instance.t('statistics.table.impressions'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'visits',
                    label: instance.t('statistics.table.visits'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                },
                {
                    key: 'clicks',
                    label: instance.t('statistics.table.clicks'),
                    width: '8.33%',
                    className: 'numeric',
                    sortable: true
                }
            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            if (!isEdit) {
                table.set('rowsPerPage', 25);
                table.set('pageSizes', [10, 25, 50])
                table.set('paginatorLocation', ['footer']);
            }

            return table;
        },

        getTableDetaliedStatistics: function () {
            var instance = this;
            var widgetList = Liferay.portal2012[instance.get('namespace') + "widgetStatisticsListSearchForm"],
                data = [],
                columns = [],
                i, j,
                len, lenJ;
            var isEdit = instance.get('widgetId') > 0;
            var widgetElement, detailsWidgetElement = [];


            if (widgetList) {
                for (i = 0, len = (widgetList.length - 1); i < len; i++) {
                    if (widgetList[i].publicationStatisticsDTOList) {
                        detailsWidgetElement = widgetList[i].publicationStatisticsDTOList;

                        for (j = 0, lenJ = detailsWidgetElement.length; j < lenJ; j++) {
                            widgetElement = detailsWidgetElement[j];
                            data.push({
                                searchTerms: widgetElement.searchTerms,
                                noSearches: widgetElement.noSearches

                            });
                        }
                    }
                }
            }

            columns = [
                {
                    key: 'searchTerms',
                    label: instance.t('statistics.table.search.terms'),
                    width: '80%',
                    className: 'numeric'
                },
                {
                    key: 'noSearches',
                    width: '20%',
                    label: instance.t('statistics.table.number.searches'),
                    sortable: true
                }

            ]

            var table = new Y.DataTable({
                columns: columns,
                data: data
            });

            table.set('rowsPerPage', 25);
            table.set('pageSizes', [10, 25, 50])
            table.set('paginatorLocation', ['footer']);


            return table;
        },

        destructWizard: function () {
            if (SUBSCRIPTION_DD_DRAG) {
                SUBSCRIPTION_DD_DRAG.detach();
            }
            if (SUBSCRIPTION_DD_DROP_HIT) {
                SUBSCRIPTION_DD_DROP_HIT.detach();
            }
            if (SUBSCRIPTION_DD_END) {
                SUBSCRIPTION_DD_END.detach();
            }
            if (SUBSCRIPTION_DD_OVER) {
                SUBSCRIPTION_DD_OVER.detach();
            }
            if (SUBSCRIPTION_DD_START) {
                SUBSCRIPTION_DD_START.detach();
            }
        },

        /**
         * Returns the DOM structure for search criteria elements, using the
         * {{#crossLink 'PublicProcurementSearchBoxWidgetWizard/AVAILABLE_CRITERIA:property'}}{{/crossLink}} property
         *
         * @method _createCriteriaElements
         * @return {HtmlElement}
         * @private
         */
        _createCriteriaElements: function () {
            var instance = this,
                children = [], i,
                defaultCriteria = AVAILABLE_CRITERIA.slice(0),
                availableCriteria = instance.get(FIELD_CRITERIA);

            defaultCriteria.sort(function (a, b) {
                var aCriteria, bCriteria;
                for (var i = 0; i < availableCriteria.length && !(aCriteria && bCriteria); i++) {
                    if (!aCriteria && availableCriteria[i].type == a.type) {
                        aCriteria = availableCriteria[i];
                    } else if (!bCriteria && availableCriteria[i].type == b.type) {
                        bCriteria = availableCriteria[i];
                    }
                }
                if (!aCriteria && !bCriteria) {
                    return 0;
                }
                if (!aCriteria) {
                    return 1;
                }
                if (!bCriteria) {
                    return -1;
                }
                if (aCriteria.weight > bCriteria.weight) {
                    return 1;
                } else {
                    return -1;
                }
            });

            for (i = 0; i < defaultCriteria.length; i++) {
                var criteria = defaultCriteria[i],
                    wrapperCssClass = 'available-criteria',
                    selected = false;

                for (var j = 0; j < availableCriteria.length; j++) {
                    if (criteria.type == availableCriteria[j].type) {
                        selected = true;
                        break;
                    }
                }

                children.push(new Y.HtmlElement({
                    label: instance.t(criteria.label),
                    wrapperCssClass: wrapperCssClass + (selected ? " active" : ''),

                    // Keep the criteria type in id
                    id: 'criteria_' + criteria.type,
                    children: [
                        new Y.InputElement({
                            type: 'hidden',
                            value: criteria.type,
                            cssClass: 'criteria-type'
                        }),
                        new Y.HtmlElement({
                            htmlContent: instance.t('searchBox.edit'),
                            cssClass: 'criteria-edit',
                            onClick: function (e) {
                                instance._doEditCriteria(e);
                            }
                        }),
                        new Y.CheckboxElement({
                            cssClass: 'criteria-toggle',
                            checked: selected ? 'true' : '',
                            onClick: function (e) {
                                instance._doSelectCriteria(e);
                            }
                        })
                    ]
                }));
            }

            return new Y.HtmlElement({
                label: instance.t('searchBox.searchCriteria'),
                cssClass: 'container-fluid container-fluid-legacy',
                children: [
                    new Y.HtmlElement({
                        cssClass: 'row-legacy',
                        children: [
                            new Y.HtmlElement({
                                cssClass: 'col-xs-6 criteria-list',
                                id: instance.get('namespace') + 'criteria_selector',
                                children: children,
                                required: true,
                                validateFunction: function () {
                                    instance.validateWidget();
                                }
                            }),
                            new Y.HtmlElement({
                                cssClass: 'col-xs-6 edit-criteria',
                                children: []
                            })
                        ]
                    })
                ]
            });
        },

        validateWidget: function () {
            var instance = this;
            var host = instance.get('host');
            var isValidated = true;
            var actionButtons = host.one("#" + instance.get('namespace') + "_buttonRow").all('.btn');

            /* validate criteria toggles list */
            var criteriaToggles = host.one('#' + instance.get('namespace') + 'criteria_selector').all('.criteria-toggle');
            var isCriteriaValidated = false;
            criteriaToggles.each(function (criteriaToggle) {
                if (criteriaToggle.get('checked')) {
                    isCriteriaValidated = true;
                }
            });
            if (!isCriteriaValidated) {
                isValidated = false;
            }

            /* validate text inputs with required attribute */
            host.all('input[required]').each(function () {
                if (this.get('type') && this.get('type') == 'text') {
                    if (!this.get('value') || this.get('value').length <= 0) {
                        isValidated = false;
                    }
                }
            });


            if (isValidated) {
                actionButtons.removeClass('disabled');
            } else {
                actionButtons.addClass('disabled');
            }
            return isValidated;
        },

        /**
         * Returns an array of available statuses and caches the result in
         * {{#crossLink 'PublicProcurementSearchBoxWidgetWizard/CRITERIA_AVAILABLE_STATUS:property'}}{{/crossLink}} property
         *
         * @method _getAvailableStatus
         * @return {Array} of objects of type {key : 'key', value: 'value'}
         * @private
         */
        _getAvailableStatus: function () {
            var instance = this;
            if (!CRITERIA_AVAILABLE_STATUS) {
                CRITERIA_AVAILABLE_STATUS = Liferay.portal2012[instance.get('namespace') + "criteriaAvailableProcurementStatus"];
            }

            return CRITERIA_AVAILABLE_STATUS;
        },

        /**
         * Returns the URL used by AutoComplete to search in the server for CPV values
         *
         * @method _getValuesCPV
         * @return {String}
         * @private
         */
        _getValuesCPV: function () {
            var instance = this,
                defaultLanguage = instance.getDefaultLanguage();
            return '/o/opportal-service/autocomplete/cpv?language=' + defaultLanguage + '&chars={query}';
        },

        /**
         * Returns the URL used by AutoComplete to search in the server for NUTS values
         *
         * @method _getValuesNUTS
         * @return {String}
         * @private
         */
        _getValuesNUTS: function () {
            var instance = this,
                defaultLanguage = instance.getDefaultLanguage();
            return '/o/opportal-service/autocomplete/nuts?language=' + defaultLanguage + '&chars={query}';
        },

        /**
         * Callback method executed when the user presses edit on a selected criteria
         *
         * @method _doEditCriteria
         * @param e
         * @private
         */
        _doEditCriteria: function (e) {
            var instance = this,
                host = instance.get('host'),
                editArea = host.one('.edit-criteria'),
                criteriaSelectedElement = Y.one(e.currentTarget).ancestor("div.available-criteria"),
                criteriaId = criteriaSelectedElement.one('.criteria-type').get('value'),
                criteria, i, tempCriteria, selectedCriteria, valuesElement, messageBubble;
            var renderElementList = [];


            editArea.empty();

            for (i = 0; i < AVAILABLE_CRITERIA.length; i++) {
                tempCriteria = AVAILABLE_CRITERIA[i];
                if (criteriaId == tempCriteria.type) {
                    criteria = tempCriteria;
                    break;
                }
            }

            for (i = 0; i < instance.get(FIELD_CRITERIA).length; i++) {
                tempCriteria = instance.get(FIELD_CRITERIA)[i];
                if (criteriaId == tempCriteria.type) {
                    selectedCriteria = tempCriteria;
                    break;
                }
            }

            if (!criteria || !selectedCriteria) {
                return;
            }

            if (criteria.valuesCallback && !criteria.useAjax) {
                valuesElement = new Y.SelectBoxElement({
                    label: instance.t('searchBox.defaultValue'),
                    name: 'defaultValue',
                    cssClass: 'default-value',
                    options: instance[criteria.valuesCallback](),
                    value: selectedCriteria.defaultValue,
                    multiple: criteria.multiple ? true : false
                });

                if (criteria.multiple) {
                    messageBubble = new Y.HtmlElement({
                        wrapperCssClass: 'glyphicon glyphicon-asterisk',
                        cssClass: 'info-message',
                        htmlContent: instance.t('baseWidgetList.message.help')
                    });
                }
            } else if (criteria.valuesCallback && criteria.useAjax) {
                valuesElement = new Y.AutoCompleteElement({
                    label: instance.t('searchBox.defaultValue'),
                    name: 'defaultValue',
                    cssClass: 'default-value',
                    selectedOptions: selectedCriteria.defaultValue,
                    cacheNamespace: "publicProcurementSearchBoxWidgetWizard" + criteria.type,
                    source: instance[criteria.valuesCallback]()
                });
            } else {
                valuesElement = new Y.InputElement({
                    label: instance.t('searchBox.defaultValue'),
                    name: 'defaultValue',
                    cssClass: 'default-value',
                    value: selectedCriteria.defaultValue && selectedCriteria.defaultValue.length > 0 ? selectedCriteria.defaultValue[0] : ""
                });
            }

            /**
             * Construction of the render list of elements
             */

            renderElementList.push(
                new Y.CheckboxElement({
                    label: instance.t('searchBox.visibleToUsers'),
                    name: 'visibleToUsers',
                    cssClass: 'visible-to-users',
                    value: 1,
                    checked: selectedCriteria.visibleToUsers
                })
            );

            renderElementList.push(
                new Y.CheckboxElement({
                    label: instance.t('searchBox.criteriaMandatory'),
                    name: 'criteriaMandatory',
                    cssClass: 'criteria-mandatory',
                    value: 1,
                    checked: selectedCriteria.criteriaMandatory
                })
            );

            renderElementList.push(valuesElement);

            //If there is no help message
            if (messageBubble != undefined) {
                renderElementList.push(messageBubble);
            }


            renderElementList.push(
                new Y.InputElement({
                    label: instance.t('searchBox.cssClass'),
                    name: 'cssClass',
                    cssClass: 'css-class',
                    value: selectedCriteria.cssClass
                })
            );

            renderElementList.push(
                new Y.HtmlElement({
                    cssClass: 'button-row',
                    children: [
                        new Y.HtmlElement({
                            element: 'button',
                            cssClass: 'btn btn-primary',
                            htmlContent: instance.t('searchBox.save'),
                            onClick: function (e) {
                                var allCriteria = instance.get(FIELD_CRITERIA);
                                selectedCriteria.visibleToUsers = editArea.one('.visible-to-users').get('checked');
                                selectedCriteria.criteriaMandatory = editArea.one('.criteria-mandatory').get('checked');
                                if (criteria.valuesCallback && !criteria.useAjax) {
                                    selectedCriteria.defaultValue = editArea.one('.default-value').all('option:checked').get('value');
                                } else if (criteria.useAjax) {
                                    selectedCriteria.defaultValue = valuesElement.get("selectedOptions");
                                } else {
                                    selectedCriteria.defaultValue = [editArea.one('.default-value').get('value')];
                                }
                                selectedCriteria.cssClass = editArea.one('.css-class').get('value');

                                for (i = 0; i < allCriteria.length; i++) {
                                    if (selectedCriteria.type == allCriteria.type) {
                                        break;
                                    }
                                }

                                if (i < allCriteria.length) {
                                    allCriteria.splice(i, 1, selectedCriteria);
                                }

                                editArea.empty();
                            }
                        }),
                        new Y.HtmlElement({
                            element: 'button',
                            cssClass: 'btn',
                            htmlContent: instance.t('searchBox.cancel'),
                            onClick: function (e) {
                                editArea.empty();
                            }
                        })
                    ]
                })
            )

            new Y.HtmlElement({
                label: instance.t(criteria.label),
                children: renderElementList
            }).render(editArea);
        },


        /**
         * Callback method executed when the user selects the criteria
         *
         * @method _doSelectCriteria
         * @param e
         * @private
         */
        _doSelectCriteria: function (e) {
            var instance = this,
                criteriaSelected = Y.one(e.currentTarget).ancestor("div.available-criteria"),
                criteriaId = criteriaSelected.one('.criteria-type').get('value'),
                criteria, i;

            criteriaSelected.toggleClass('active');

            for (i = 0; i < AVAILABLE_CRITERIA.length; i++) {
                var tempCriteria = AVAILABLE_CRITERIA[i];
                if (criteriaId == tempCriteria.type) {
                    criteria = tempCriteria;
                    break;
                }
            }

            if (!criteria) {
                return;
            }

            if (criteriaSelected.hasClass('active')) {
                instance._doAddCriteria(criteria, criteriaSelected);
            } else {
                instance._doRemoveCriteria(criteria);
            }
        },

        /**
         * Adds a criteria in the {{#crossLink 'PublicProcurementSearchBoxWidgetWizard/criteria:attribute'}}{{/crossLink}} attribute
         *
         * @method _doAddCriteria
         * @param criteria
         * @param criteriaSelected
         * @private
         */
        _doAddCriteria: function (criteria, criteriaSelected) {
            var instance = this, i,
                availableCriteria = instance.get(FIELD_CRITERIA),
                criteriaList = Y.one('.criteria-list').all('div.available-criteria'),
                weight = criteriaList.indexOf(criteriaSelected);

            for (i = 0; i < availableCriteria.length; i++) {
                if (criteria.type == availableCriteria[i].type) {
                    return;
                }
            }

            availableCriteria.push({
                type: criteria.type,
                visibleToUsers: criteria.defaultVisible,
                criteriaMandatory: criteria.defaultMandatory,
                defaultValue: [],
                cssClass: '',
                weight: weight
            });
            instance.set(FIELD_CRITERIA, availableCriteria);
            instance.resetCriteriaWeights();
        },

        /**
         * Removes a criteria from the {{#crossLink 'PublicProcurementSearchBoxWidgetWizard/criteria:attribute'}}{{/crossLink}} attribute
         *
         * @method _doRemoveCriteria
         * @param criteria
         * @private
         */
        _doRemoveCriteria: function (criteria) {
            var instance = this, i,
                host = instance.get('host'),
                editArea = host.one('.edit-criteria'),
                availableCriteria = instance.get(FIELD_CRITERIA);

            for (i = 0; i < availableCriteria.length; i++) {
                if (criteria.type == availableCriteria[i].type) {
                    break;
                }
            }

            if (i < availableCriteria.length) {
                availableCriteria.splice(i, 1);
            }
            instance.set(FIELD_CRITERIA, availableCriteria);
            editArea.empty();
        },

        /**
         * Adds drop down events for the criteria list
         *
         * @method _addDropDownEvents
         * @private
         */
        _addDropDownEvents: function () {
            var instance = this;
            //Listen for all drop:over events
            SUBSCRIPTION_DD_OVER = Y.DD.DDM.on('drop:over', function (e) {
                //Get a reference to our drag and drop nodes
                var drag = e.drag.get('node'),
                    drop = e.drop.get('node');

                //Are we dropping on a li node?
                if (drop.hasClass('available-criteria')) {
                    //Are we not going up?
                    if (!goingUp) {
                        drop = drop.get('nextSibling');
                    }
                    //Add the node to this list
                    e.drop.get('node').get('parentNode').insertBefore(drag, drop);
                    //Resize this nodes shim, so we can drop on it later.
                    e.drop.sizeShim();
                }
            });

            //Listen for all drag:drag events
            SUBSCRIPTION_DD_DRAG = Y.DD.DDM.on('drag:drag', function (e) {
                //Get the last y point
                var y = e.target.lastXY[1];
                //is it greater than the lastY var?
                if (y < lastY) {
                    //We are going up
                    goingUp = true;
                } else {
                    //We are going down.
                    goingUp = false;
                }
                //Cache for next check
                lastY = y;
            });

            //Listen for all drag:start events
            SUBSCRIPTION_DD_START = Y.DD.DDM.on('drag:start', function (e) {
                //Get our drag object
                var drag = e.target;
                //Set some styles here
                drag.get('node').setStyle('opacity', '.25');
                drag.get('dragNode').set('innerHTML', drag.get('node').get('innerHTML'));
                drag.get('dragNode').setStyles({
                    opacity: '.5',
                    borderColor: drag.get('node').getStyle('borderColor'),
                    backgroundColor: drag.get('node').getStyle('backgroundColor')
                });
            });
            //Listen for a drag:end events
            SUBSCRIPTION_DD_END = Y.DD.DDM.on('drag:end', function (e) {
                var drag = e.target;
                //Put our styles back
                drag.get('node').setStyles({
                    visibility: '',
                    opacity: '1'
                });
            });
            //Listen for all drag:drophit events
            SUBSCRIPTION_DD_DROP_HIT = Y.DD.DDM.on('drag:drophit', function (e) {
                var drop = e.drop.get('node'),
                    drag = e.drag.get('node');

                //if we are not on a child, we must have been dropped on a parent
                if (drop.hasClass('criteria-list')) {
                    if (!drop.contains(drag)) {
                        drop.appendChild(drag);
                    }
                }
                instance.resetCriteriaWeights();
            });
        },


        /**
         * Resets the criteria weights
         *
         * @method resetCriteriaWeights
         * @private
         */
        resetCriteriaWeights: function () {
            var instance = this, j, i, type,
                availableCriteria = instance.get(FIELD_CRITERIA),
                criteriaList = Y.one('.criteria-list') ? Y.one('.criteria-list').all('.criteria-type') : [];

            for (j = 0; j < availableCriteria.length; j++) {
                for (i = 0; i < criteriaList.size(); i++) {
                    type = criteriaList.item(i).get('value');
                    if (type == availableCriteria[j].type) {
                        availableCriteria[j].weight = i;
                        break;
                    }
                }
            }
            ;
            instance.set(FIELD_CRITERIA, availableCriteria);
        }
    });

    Y.namespace('Plugin').PublicProcurementSearchBoxWidgetWizard = PublicProcurementSearchBoxWidgetWizard;

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'node',
        'base-build',
        'plugin',
        'classnamemanager',
        'attribute-base',
        'io-base',
        'history-hash',
        'wizardTools',
        'baseWidgetList',
        'formWidget',
        'dd-constrain',
        'dd-proxy',
        'dd-drop',
        'autocomplete',
        'datatype'
    ]
});
var openPopup = function (url, title) {
    AUI().use('node', 'opportal-dialog', function (Y) {
        Y.opportalDialog.show(url, title ? title : '', 'auto');
    });
};
/**
 * This module generates the semantic search widget wizard
 *
 * @module wizardTools
 * @requires opportalDialog
 */
YUI.add('wizardTools', function (Y) {
    var
            /**
             * Keeps the class name manager to generate yui namespace classes
             *
             * @attribute getCN
             * @type {function}
             * @static
             * @final
             */
            getCN = Y.ClassNameManager.getClassName,

            /**
             * Keeps the processed class that will be attached on the main element to prevent double processing
             *
             * @attribute CLS_PROCESSED
             * @type {String}
             * @static
             * @final
             */
            CLS_PROCESSED = getCN('wizardTools'),

            /**
             * Keeps the HashChange event
             *
             * @attribute EVENT_HASH_CHANGE
             * @type {String}
             * @static
             * @final
             * @deprecated
             */
            EVENT_HASH_CHANGE = 'hashchange',

            /**
             * Keeps the url executed to save a widget
             *
             * @attribute URL_SAVE_WIDGET
             * @type {String}
             * @static
             */
            URL_SAVE_WIDGET,

            /**
             * Keeps the url executed to preview a widget
             *
             * @attribute URL_PREVIEW_WIDGET
             * @type {String}
             * @static
             */
            URL_PREVIEW_WIDGET,

            /**
             * Keeps the url executed to return to widgets list
             *
             * @attribute URL_RETURN_TO_MY_WIDGETS
             * @type {String}
             * @static
             */
            URL_RETURN_TO_MY_WIDGETS,

            /**
             * Keeps the url executed to get a widget
             *
             * @attribute URL_GET_WIDGET
             * @type {String}
             * @static
             */
            URL_GET_WIDGET,

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_SEARCH_BOX
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_SEARCH_BOX = "1",

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_SEARCH_RESULTS
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_SEARCH_RESULTS = "2",

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_PUBLICATION_VIEW
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_PUBLICATION_VIEW = "3",

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_SEMANTIC_SEARCH
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_SEMANTIC_SEARCH = "4",

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_PUBLICATION_DETAIL
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_PUBLICATION_DETAIL = "5",

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_ORGANIZATION
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_ORGANIZATION = "6",

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_PUBLIC_PROCUREMENT_SEARCH
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_PUBLIC_PROCUREMENT_SEARCH = '7',

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_PUBLIC_PROCUREMENT_SEARCH_RESULT
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_PUBLIC_PROCUREMENT_SEARCH_RESULT = '8',

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_PUBLIC_PROCUREMENT_SELECTED
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_PUBLIC_PROCUREMENT_SELECTED = '9',

            /**
             * Keeps the widget type id for validation
             *
             * @attribute WIDGET_TYPE_PUBLIC_PROCUREMENT_DETAILS
             * @type {string}
             * @static
             * @final
             */
            WIDGET_TYPE_PUBLIC_PROCUREMENT_DETAILS = '10',

            /**
             * Keeps the loader node, to display while the widget wizard is loading
             *
             * @attribute LOADER
             * @type {Node}
             * @static
             */
            LOADER = undefined,

            /**
             * Event fired when all calls are finished
             *
             * @event loadCallFinished
             * @type {string}
             * @static
             */
            EVENT_LOAD_CALL_FINISHED = 'loadCallFinished',

            /**
             * default properties from YUI and other cyclic properties
             * @attribute RESERVED_ATTRS
             * @type {Array}
             * @static
             * @final
             */
            RESERVED_ATTRS = ['host', 'destroyed', 'initialized', 'templateList'],

            /**
             * Keeps the labels translations
             *
             * @attribute TRANSLATED_LABELS
             * @static
             */
            TRANSLATED_LABELS,

            /**
             * Keeps the default language
             *
             * @attribute DEFAULT_LANGUAGE
             * @static
             */
            DEFAULT_LANGUAGE,

            /**
             * Keeps the available languages
             *
             * @attribute AVAILABLE_LANGUAGES
             * @static
             */
            AVAILABLE_LANGUAGES,

            LANG_OPTION = 'languageOptionSelection',
            LANG_OPTION_SELECTION = 'languageOptionSelectedLang',
            SELECTED_LANGUAGE_OPTION = {
                AUTO: 'auto',
                MANUAL: 'manual'
            },

            FIELD_LANGUAGE = 'language',
            FIELD_LANGUAGE_CALLBACK = 'languageCallback',

            PREVIEW_BOX = 'previewBox',
            PREVIEW_BOX_NODE = undefined,
            PREVIEW_BOX_REFRESH = 'previewRefresh',
            CLEAR_CACHE = 'clearCache',
            /**
             * Keeps the url executed to save a widget
             *
             * @attribute URL_SAVE_WIDGET
             * @type {String}
             * @static
             */
            URL_NO_ACTION_SAVE_WIDGET;

    /**
     * This is an abstract class, further extended by all other wizard classes
     *
     * @param cfg
     * @class AbstractWizard
     * @constructor
     * @extends Plugin.Base
     */
    var AbstractWizard = function (cfg) {
        AbstractWizard.superclass.constructor.apply(this, arguments);
    };

    AbstractWizard.ATTRS = {

        /**
         * The unique namespace for this portlet
         *
         * @attribute namespace
         * @type {String}
         * @default ''
         */
        namespace: {
            value: ''
        },

        /**
         * The systemId under which this portlet executes
         *
         * @attribute systemId
         * @type {String}
         * @default ''
         * @deprecated
         */
        systemId: {
            value: ''
        },

        /**
         * The widget id to be send to the portlet action, if is editable
         *
         * @attribute widgetId
         * @type {Number}
         * @default 0
         */
        widgetId: {
            value: 0
        },

        /**
         * The widget type to be send to the portlet action
         *
         * @attribute widgetType
         * @type {String}
         * @default ''
         */
        widgetType: {
            value: '',
            validator: function (val, name) {
                return (val == WIDGET_TYPE_SEARCH_BOX || val == WIDGET_TYPE_SEARCH_RESULTS ||
                    val == WIDGET_TYPE_PUBLICATION_VIEW || val == WIDGET_TYPE_SEMANTIC_SEARCH || val == WIDGET_TYPE_PUBLICATION_DETAIL || val == WIDGET_TYPE_ORGANIZATION ||
                    val == WIDGET_TYPE_PUBLIC_PROCUREMENT_SEARCH || val == WIDGET_TYPE_PUBLIC_PROCUREMENT_SEARCH_RESULT ||
                    val == WIDGET_TYPE_PUBLIC_PROCUREMENT_SELECTED || val == WIDGET_TYPE_PUBLIC_PROCUREMENT_DETAILS);
            }
        },

        /**
         * The number of calls waiting to be loaded
         *
         * @attribute loadCalls
         * @type {Int}
         * @default 0
         */
        loadCalls: {
            value: 0
        },

        /**
         * The language widget is displayed in.
         * If 'auto' is selected, the widget will try to take the language from:
         *  - URL - if the url is like /{language}/*
         *  - browser.
         *
         *  If 'callback' is selected, the callback method will be executed
         *
         * @attribute language
         * @type {String}
         * @default 'auto'
         */
        language: {
            value: 'auto'
        },

        /**
         * The language widget is displayed in.
         * If 'auto' is selected, the widget will try to take the language from:
         *  - URL - if the url is like /{language}/*
         *  - browser.
         *
         *  If 'callback' is selected, the callback method will be executed.
         *  The callback method must be a function available in the page where the widget will be placed.
         *
         * @attribute languageCallback
         * @type {String}
         * @default ''
         */
        languageCallback: {
            value: ''
        }
    };

    Y.extend(AbstractWizard, Y.Plugin.Base, {
        /**
         * Sets the {{#crossLink 'AbstractWizard/widgetType:attribute}}{{/crossLink}} accordingly
         *
         * @method setWizardType
         */
        setWizardType: function () {
        },

        /**
         * Returns language selector
         * @returns {Y.HtmlElement}
         */

        getLanguageSelector: function () {
            var instance = this;
            var langSelector;
            var languageAuto;
            var languageManual;
            var langSelectorManual;
            var langSelectorList;


            languageAuto = new Y.RadioElement({
                label: instance.t('searchResult.lang.multilingual'),
                value: SELECTED_LANGUAGE_OPTION.AUTO,
                modelInstance: instance,
                name: LANG_OPTION,
                checked: instance.get("language") == SELECTED_LANGUAGE_OPTION.AUTO ? true : false,
                id: instance.get('namespace') + "_" + LANG_OPTION + '_' + SELECTED_LANGUAGE_OPTION.AUTO,
                onChange: function (e) {
                    instance.setLanguageWidgetLanguage(instance.getDefaultLanguage(), SELECTED_LANGUAGE_OPTION.AUTO);
                }
            });


            langSelectorManual = new Y.RadioElement({
                label: instance.t('searchResult.lang.multilingual.selection'),
                value: SELECTED_LANGUAGE_OPTION.MANUAL,
                modelInstance: instance,
                wrapperCssClass: '',
                name: LANG_OPTION,
                checked: instance.get("language") != SELECTED_LANGUAGE_OPTION.AUTO ? true : false,
                id: instance.get('namespace') + "_" + LANG_OPTION + '_' + SELECTED_LANGUAGE_OPTION.MANUAL,
                onChange: function (e) {
                    instance.setLanguageWidgetLanguage(AUI().one("#" + instance.get('namespace') + LANG_OPTION_SELECTION).get('value'), SELECTED_LANGUAGE_OPTION.MANUAL);
                }
            });

            langSelectorList = new Y.SelectBoxElement({
                name: LANG_OPTION_SELECTION,
                modelInstance: instance,
                wrapperCssClass: 'col-md-2 ' + LANG_OPTION,
                options: instance.getLanguageListAvailable(),
                id: instance.get('namespace') + LANG_OPTION_SELECTION,
                defaultSelectValue: instance.get('language') && instance.get('language') != 'auto' ? instance.get('language') : '',
                onChange: function (e) {
                    instance.setLanguageWidgetLanguage(e.target.get('value'), SELECTED_LANGUAGE_OPTION.MANUAL);
                }
            });

            languageManual = new Y.HtmlElement({
                cssClass: 'row',
                children: [langSelectorManual, langSelectorList]
            });


            langSelector = new Y.HtmlElement({
                cssClass: 'sr-lang-selection',
                children: [languageAuto, languageManual]
            });


            return langSelector;

        },

        /**
         * Used by language selector
         * @param language
         * @param languageType auto/manual
         */
        setLanguageWidgetLanguage: function (language, languageType) {
            var instance = this;

            if (languageType == SELECTED_LANGUAGE_OPTION.AUTO) {
                var langNodeAuto = AUI().one("#" + instance.get('namespace') + "_" + LANG_OPTION + '_' + SELECTED_LANGUAGE_OPTION.AUTO);
                var langNodeManual = AUI().one("#" + instance.get('namespace') + "_" + LANG_OPTION + '_' + SELECTED_LANGUAGE_OPTION.MANUAL);
                langNodeManual.removeAttribute('checked');
                langNodeManual.set('checked', false);
                langNodeAuto.setAttribute('checked', true);
                langNodeAuto.set('checked', true)
                instance.setLanguage(instance.getLanguageDefaultOption());
            }

            if (languageType == SELECTED_LANGUAGE_OPTION.MANUAL) {
                var langNodeAuto = AUI().one("#" + instance.get('namespace') + "_" + LANG_OPTION + '_' + SELECTED_LANGUAGE_OPTION.AUTO);
                var langNodeManual = AUI().one("#" + instance.get('namespace') + "_" + LANG_OPTION + '_' + SELECTED_LANGUAGE_OPTION.MANUAL);
                langNodeAuto.removeAttribute('checked');
                langNodeAuto.set('checked', false);
                langNodeManual.setAttribute('checked', true);
                langNodeManual.set('checked', true)
                instance.setLanguage(language);
            }

        },

        /**
         * Returns the language nodes to be added in widget
         *
         * @method getLanguageNodes
         * @return Y.HtmlElement
         */
        getLanguageNodes: function () {
            var instance = this,
                    languages = instance.getAvailableLanguages(),
                    options = [
                        {key: 'auto', value: instance.t('wizard.auto')},
                        {key: 'callback', value: instance.t('wizard.callback')}
                    ], i;

            for (i = 0; i < languages.length; i++) {
                options.push({key: languages[i], value: languages[i]});
            }

            var nodeChildren = [
                new Y.SelectBoxElement({
                    label: instance.t('wizard.language'),
                    modelInstance: instance,
                    name: FIELD_LANGUAGE,
                    options: options,
                    onChange: function (e) {
                        var node = Y.one(e.currentTarget),
                                value = node.get('value');
                        if (value == 'callback') {
                            Y.all('.language-callback').removeClass('hidden');
                        }
                        else {
                            Y.all('.language-callback').addClass('hidden');
                        }
                    }
                }),
                new Y.InputElement({
                    label: instance.t('wizard.languageCallback'),
                    modelInstance: instance,
                    name: FIELD_LANGUAGE_CALLBACK,
                    wrapperCssClass: 'language-callback' + (instance.get(FIELD_LANGUAGE) == 'callback' ? '' : ' hidden')
                })
            ];

            return new Y.HtmlElement({
                children: nodeChildren
            });

        },

        /**
         * Returns the language nodes without automatic options to be added in widget
         *
         * @method getLanguageNodes
         * @return Y.HtmlElement
         */
        getLanguageAvailableNodes: function () {
            var instance = this,
                    languages = instance.getAvailableLanguages(),
                    options = new Array(), i;

            for (i = 0; i < languages.length; i++) {
                options.push({key: languages[i], value: languages[i]});
            }

            var nodeChildren = [
                new Y.SelectBoxElement({
                    label: instance.t('wizard.language'),
                    modelInstance: instance,
                    name: FIELD_LANGUAGE,
                    options: options,
                    onChange: function (e) {
                        var node = Y.one(e.currentTarget),
                                value = node.get('value');
                        if (value == 'callback') {
                            Y.all('.language-callback').removeClass('hidden');
                        }
                        else {
                            Y.all('.language-callback').addClass('hidden');
                        }
                    }
                }),
                new Y.InputElement({
                    label: instance.t('wizard.languageCallback'),
                    modelInstance: instance,
                    name: FIELD_LANGUAGE_CALLBACK,
                    wrapperCssClass: 'language-callback' + (instance.get(FIELD_LANGUAGE) == 'callback' ? '' : ' hidden'),
                    value: 'en'
                })
            ];


            return new Y.HtmlElement({
                children: nodeChildren
            });

        },

        getLanguageListAvailable: function () {
            var instance = this,
                    languages = instance.getAvailableLanguages(),
                    options = new Array(), i;
            for (i = 0; i < languages.length; i++) {
                options.push({key: languages[i], value: languages[i]});
            }
            return options;
        },

        setLanguage: function (language) {
            var instance = this;
            instance.set('language', language);
        },

        attachPreviewPanel: function (host, refreshAction, clearCacheAction) {
            var instance = this;
            new Y.PanelElement({
                label: '<span>' + instance.t('wizard.preview') + '</span>' +
                '<button id="' + PREVIEW_BOX_REFRESH + '" class="btn btn-primary btn-sm">' +
                instance.t('wizard.refresh') +
                ' <i class="icon-refresh"></i>' +
                '</button>' +
                '<button id="' + CLEAR_CACHE + '" class="btn btn-primary btn-sm">' +
                instance.t('clear.cache') +
                '</button>',
                wrapperCssClass: 'refresh-panel hidden',
                id: 'widgetPreviewPanel',
                children: [
                    new Y.HtmlElement({
                        id: PREVIEW_BOX,
                        cssClass: 'preview-box',
                        wrapperCssClass: 'widget-display-options col-md-12',
                        modelInstance: instance
                    })
                ]
            }).render(host);
            Y.one('#' + PREVIEW_BOX_REFRESH).on('click', refreshAction);
            var clearCacheButton = Y.one('#' + CLEAR_CACHE);
            clearCacheButton.on('click', clearCacheAction);
            clearCacheButton.on('click', refreshAction);
        },

        displayPreviewNode: function (display) {
            var previewPanel = Y.one('#' + 'widgetPreviewPanel');
            if (PREVIEW_BOX_NODE === undefined) {
                PREVIEW_BOX_NODE = Y.one('#' + PREVIEW_BOX);
            }
            if (display) {
                PREVIEW_BOX_NODE.ancestor().ancestor().ancestor().removeClass('hidden');
                if (previewPanel) {
                    previewPanel.removeClass('hidden');
                }
            }
            else {
                PREVIEW_BOX_NODE.ancestor().ancestor().ancestor().addClass('hidden');
                if (previewPanel) {
                    previewPanel.addClass('hidden');
                }
            }
        },

        /**
         * Sets the {{#crossLink 'AbstractWizard/loadCalls:attribute}}{{/crossLink}} accordingly
         *
         * @method setLoadCalls
         */
        setLoadCalls: function () {
        },

        /**
         * Implements the plugin initializer method
         *
         * @method initializer
         */
        initializer: function () {
            var instance = this, host = this.get('host');

            if (host.hasClass(CLS_PROCESSED)) {
                return;
            }
            host.addClass(CLS_PROCESSED);

            // on hash change
            /*Y.on(EVENT_HASH_CHANGE, function (e) {
             Y.wizardTools.apply(instance, e.newHash);
             }, Y.config.win);*/

            Y.on(EVENT_LOAD_CALL_FINISHED, function () {
                instance.onLoadCallFinished(instance);
            });

            // pre initialization
            instance.setWizardType();
            instance.setLoadCalls();

            this.setLoading(host);
            this.asyncInitWizard(host, this.removeLoading);
        },

        /**
         * Method executed when the all the calls triggered by the modules are finished
         *
         * @method onLoadCallFinished
         * @param instance
         */
        onLoadCallFinished: function (instance) {
            var loadCalls = instance.get("loadCalls");
            instance.set("loadCalls", (loadCalls - 1));
        },

        /**
         * Fires the EVENT_LOAD_CALL_FINISHED event
         *
         * @method fireLoadCallFinished
         */
        fireLoadCallFinished: function () {
            Y.fire(EVENT_LOAD_CALL_FINISHED);
        },

        /**
         * Initializes the wizard asynchronously
         *
         * @method asyncInitWizard
         * @param host
         * @param callback execute this when the wizard is loaded
         */
        asyncInitWizard: function (host, callback) {
            var instance = this;

            var promise = new Y.Promise(function (resolve, reject) {
                //console.log('executing promise');
                var promisedValue = true;

                instance.initWizard();

                try {
                    resolve(promisedValue);
                } catch (exception) {
                    console.log('asyncInitWizard error:', exception);
                    reject(exception);
                }
            });

            var resolve = function (promisedValue) {
                //console.log('calling resolve.');
                var interval = setInterval(function () {
                    //console.log('checking loadCalls: ' + instance.get("loadCalls"));
                    if (instance.get("loadCalls") == 0) {
                        stop();
                    }
                }, 500);
                var stop = function () {
                    clearInterval(interval);
                    callback(host);
                };
            };
            var reject = function (reasonForFailure) {
                console.log('calling reject: ' + reasonForFailure);
            };

            promise.then(resolve, reject);
        },

        /**
         * Creates loader node instance
         *
         * @method getNewLoader
         * @return {Node}
         */
        getNewLoader: function () {
            return Y.Node.create('<div id="blocking-loader" class="portal-loader" aria-busy="true">' +
                    '<span class="loading-image"></span>' +
                    '</div>');
        },

        /**
         * Displays a loader node and hides the widget wizard until load is completed
         *
         * @method setLoading
         * @param host
         */
        setLoading: function (host) {
            if (LOADER != undefined) {
                return;
            }

            LOADER = this.getNewLoader();
            host.addClass('hidden');
            host.ancestor().append(LOADER);
        },

        /**
         * Removes a loader node and displays the widget wizard
         *
         * @method removeLoading
         * @param host
         */
        removeLoading: function (host) {
            //console.log('executing removeLoading');
            if (LOADER == undefined) {
                return;
            }

            LOADER.remove(true);
            LOADER = undefined;
            host.removeClass('hidden');
        },

        /**
         * Method to return the processed class to be added on the node
         *
         * @method getProcessedClass
         * @return {String}
         */
        getProcessedClass: function () {
            return CLS_PROCESSED;
        },

        /**
         * Method used to translate all labels in the wizard
         *
         * @method t
         * @param label
         * @return {String}
         */
        t: function (label) {
            var instance = this;
            if (!TRANSLATED_LABELS) {
                TRANSLATED_LABELS = Liferay.portal2012[instance.get('namespace') + "translatedLabels"];
            }

            return TRANSLATED_LABELS && TRANSLATED_LABELS.hasOwnProperty(label) ? TRANSLATED_LABELS[label] : label;
        },

        /**
         * Gets the default language from Liferay, previously set in view.jsp
         *
         * @method getDefaultLanguage
         * @return {String} default language id
         */
        getDefaultLanguage: function () {
            var instance = this;
            if (!DEFAULT_LANGUAGE) {
                DEFAULT_LANGUAGE = Liferay.portal2012[instance.get('namespace') + "defaultLanguage"];
            }

            return DEFAULT_LANGUAGE;
        },

        getLanguageDefaultOption: function () {
            return "auto";
        },

        /**
         * Gets the available languages from Liferay, previously set in view.jsp
         *
         * @method getAvailableLanguages
         * @return {Array} available languages
         */
        getAvailableLanguages: function () {
            var instance = this;
            if (!AVAILABLE_LANGUAGES) {
                AVAILABLE_LANGUAGES = Liferay.portal2012[instance.get('namespace') + "availableLanguages"];
            }

            return AVAILABLE_LANGUAGES;
        },
        /**
         * Implements the plugin destructor method
         *
         * @method destructor
         */
        destructor: function () {
            var instance = this,
                    host = this.get('host');
            Y.detach(EVENT_LOAD_CALL_FINISHED);
            host.removeClass(instance.getProcessedClass());
            host.empty();
            instance.destructWizard();
        },

        /**
         * Executes destroy methods specific to each wizard
         *
         * @method destructWizard
         */
        destructWizard: function () {
        },

        /**
         * Executes init methods specific to each wizard
         *
         * @method initWizard
         */
        initWizard: function () {
        },

        /**
         * Displays a confirmation message
         *
         * @method areYouSure
         * @return {Boolean}
         */
        areYouSure: function () {
            var instance = this;
            return confirm(instance.t('wizard.areYouSure'));
        },

        /**
         * Process method for the save button
         *
         * @method doSaveWidget
         * @param completeCallback
         * @async
         */
        doSaveWidget: function (completeCallback) {
            var attrs = {},
                    instance = this,
                    allAttributes = instance.getAttrs(),
                    namespace = instance.get('namespace'),
                    instanceName = instance.name,
                    cellarIds = instance.get("cellarIDs"),
                    saveWidgetURL;

            for (var property in allAttributes) {
                if (allAttributes.hasOwnProperty(property) && !RESERVED_ATTRS.contains(property)) {
                    attrs[property] = instance.get(property);
                }
            }

            completeCallback || (completeCallback = function () {
            });

            if (!URL_SAVE_WIDGET) {
                URL_SAVE_WIDGET = Liferay.portal2012[instance.get('namespace') + "saveUrl"];
            }

            if (!URL_NO_ACTION_SAVE_WIDGET) {
                URL_NO_ACTION_SAVE_WIDGET = Liferay.portal2012[instance.get('namespace') + "saveNoActionURL"];
            }

            saveWidgetURL = ((instanceName == "PublicationViewWidgetWizard") && (cellarIds.length == 0)) ? URL_NO_ACTION_SAVE_WIDGET : URL_SAVE_WIDGET;

            if (saveWidgetURL) {

                var modal = new Y.Modal({
                    bodyContent: '<div id="blocking-loader" class="portal-loader" aria-busy="true">' +
                    '<span class="loading-image"></span>' +
                    '</div>',
                    centered: true,
                    modal: true,
                    render: '#' + instance.get('host').get('id'),
                    width: 500,
                    zIndex: 1000
                }).render();

                Y.io(saveWidgetURL, {
                    method: 'POST',
                    data: Y.JSON.stringify(attrs),
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    on: {
                        success: function (id, response) {
                            var responseHtml = response.responseText.trim();
                            modal.set('bodyContent', responseHtml);
                            // set new widget id
                            if (instance.get('widgetId') == 0 && responseHtml) {

                                var widgetId= response.getResponseHeader("widgetId");
                                if(widgetId===null||widgetId==undefined){
                                    var matcher = responseHtml.match(/(?:widgetId=\s\&#034;)([0-9]*)(?:\&#034;)/);
                                    var widgetId = matcher && matcher.length > 1 ? responseHtml.match(/(?:widgetId=\s\&#034;)([0-9]*)(?:\&#034;)/)[1] : 0;
                                }
                                if (widgetId && widgetId > 0) {
                                    instance.set('widgetId', widgetId);
                                    instance.validateGetButton();
                                }
                            }
                            completeCallback(instance, responseHtml);
                        },
                        failure: function (id, response) {
                            modal.set('bodyContent', '<div class="alert alert-error">' +
                                    instance.t('wizard.save.failed') + '</div>');

                        }
                    }
                });
            }
        },

        /**
         * Process method for the preview button
         *
         * @method doPreviewWidget
         * @param completeCallback
         * @async
         */
        doPreviewWidget: function (completeCallback) {
            var attrs = {},
                    instance = this,
                    allAttributes = instance.getAttrs(),
                    ioCfg;
            for (var property in allAttributes) {
                if (allAttributes.hasOwnProperty(property) && !RESERVED_ATTRS.contains(property)) {
                    attrs[property] = instance.get(property);
                }
            }
            completeCallback || (completeCallback = function () {
            });

            ioCfg = {
                method: 'POST',
                data: Y.JSON.stringify(attrs),
                headers: {
                    'Content-Type': 'application/json'
                },
                on: {
                    complete: function (e) {
                        completeCallback(e);
                    }
                }
            };

            if (!URL_PREVIEW_WIDGET) {
                URL_PREVIEW_WIDGET = Liferay.portal2012[instance.get('namespace') + "previewUrl"];
            }

            if (URL_PREVIEW_WIDGET) {
                var node = Y.one('#' + PREVIEW_BOX);
                node.ancestor().ancestor().ancestor().removeClass('hidden');
                node.set("innerHTML", '<div id="blocking-loader" class="portal-loader" aria-busy="true">' +
                        '<span class="loading-image"></span>' +
                        '</div>');
                var dispatcher = new Y.Dispatcher({
                    node: node,
                    ioConfig: ioCfg
                });
                setTimeout(function () {
                    dispatcher.set('uri', URL_PREVIEW_WIDGET);
                }, 10);
            }
        },

        /**
         * Process method for the preview button
         *
         * @method doPreviewWidget
         * @param completeCallback
         * @async
         */
        doReturnToMyWidgets: function () {
            var instance = this,
                    namespace = instance.get('namespace');

            if (!URL_RETURN_TO_MY_WIDGETS) {
                URL_RETURN_TO_MY_WIDGETS = Liferay.portal2012[instance.get('namespace') + "backToWidgetListURL"];
            }

            if (URL_RETURN_TO_MY_WIDGETS) {
                window.location = URL_RETURN_TO_MY_WIDGETS;
            }
        },

        /**
         * Process method for the get widget button
         *
         * @method doGetWidget
         * @param completeCallback
         * @async
         */
        doGetWidget: function (completeCallback) {
            var attrs = {},
                    instance = this,
                    allAttributes = instance.getAttrs(),
                    namespace = instance.get('namespace');
            for (var property in allAttributes) {
                if (allAttributes.hasOwnProperty(property) && !RESERVED_ATTRS.contains(property)) {
                    attrs[property] = instance.get(property);
                }
            }

            completeCallback || (completeCallback = function () {
            });

            if (!URL_GET_WIDGET) {
                URL_GET_WIDGET = Liferay.portal2012[instance.get('namespace') + "getUrl"];
            }

            if (URL_GET_WIDGET) {
                var modal = new Y.Modal({
                    bodyContent: '<div id="blocking-loader" class="portal-loader" aria-busy="true">' +
                    '<span class="loading-image"></span>' +
                    '</div>',
                    centered: true,
                    modal: true,
                    render: '#' + instance.get('host').get('id'),
                    width: 500,
                    zIndex: 1000
                }).render();

                Y.io(URL_GET_WIDGET, {
                    method: 'POST',
                    data: Y.JSON.stringify(attrs),
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    on: {
                        success: function (id, response) {
                            var responseHtml = response.responseText.trim();
                            modal.set('bodyContent', responseHtml);
                            completeCallback(instance, responseHtml);
                        },
                        failure: function (id, response) {
                            modal.set('bodyContent', '<div class="alert alert-error">' +
                                    instance.t('wizard.save.failed') + '</div>');
                        }
                    }
                });
            }

        },

        /**
         * Executes validateWidget methods specific to each wizard
         *
         * @method validateWidget
         */
        validateWidget: function () {
            return true;
        },

        validateGetButton: function () {
            var instance = this;
            var host = instance.get('host');
            var actionGetButtons = host.one("#" + instance.get('namespace') + "_buttonRow").one('.get-button');

            if (instance.get('widgetId')) {
                actionGetButtons.removeClass('hidden');
            }
            else {
                actionGetButtons.addClass('hidden');
            }
        },
    });

    Y.AbstractWizard = AbstractWizard;

    /**
     * This class provides tools to serialize the attributes object
     *
     * @class wizardTools
     * @type {{apply: apply, toObject: toObject, toQueryString: toQueryString}}
     */
    Y.wizardTools = {
        /**
         * Applies the configurations from the hash string to the object
         *
         * @method apply
         * @param object {AbstractWizard}
         * @param hash {String}
         */
        apply: function (object, hash) {
            var cfg = this.toObject(hash);
            if (cfg && object.setAttrs) {
                object.setAttrs(cfg);
            }
        },

        /**
         * Deserialize a query string into an object
         *
         * @method toObject
         * @param hash {String}
         * @return {Object}
         */
        toObject: function (hash) {
            if (hash && hash.length > 0) {
                return Y.QueryString.parse(hash);
            }
            return null;
        },

        /**
         * Serializes an object into a query string
         *
         * @method toQueryString
         * @param object {Object}
         * @return {String}
         */
        toQueryString: function (object) {
            return Y.QueryString.stringify(object);
        }
    };

}, 'portalop-2014.05.28-17-20', {
    requires: [
        'node',
        'base-build',
        'plugin',
        'classnamemanager',
        'attribute-base',
        'io-base',
        'history-hash',
        'querystring-parse-simple',
        'querystring-stringify-simple',
        'io-base',
        'json-stringify',
        'opportal-dialog',
        'promise',
        'slider',
        'dial',
        'color',
        'event-valuechange'
    ]
});
