/**
 * @class de_epages.presentation.tray.contentgeneralview
 * @author Copyright 2006-2013, epages GmbH, All Rights Reserved
 *
 * The tray's main view for use without a dialog
 *
 * ### Example
 *
 *     $('.ep-tray').uiTray({
 *         label: 'Add Products',
 *         smartsearch: 'JSONSmartSearchProductAlias',
 *         tabs: {
 *             products: {
 *                 id: #Shop.Products.id
 *                 action: 'JSONSearchProductsToInsert',
 *                 additionslContent: '<a href="#">Additional content</a>'
 *             }
 *         }
 *     });
 *
 * @uses jQuery
 * @uses jQuery.ui.tabs
 * @uses Backbone
 *
 * @return {Object} Mainview
 */

/*jslint browser: true*/
/*globals define*/

define('de_epages/presentation/tray/content-view', [
    'jquery',
    'backbone',
    '$tmpl!./content-view',
    '$dict!../dictionary',
    'ep',

    'jquery/metaparse',
    'ep/ui/input',
    'ep/ui/datatable'
], function ($, Backbone, template, dict, ep) {
    'use strict';

    return Backbone.View.extend({
        context: undefined,
        tagname: 'div',
        template: template,
        renderedTemplate: '',

        /*
         * Setting some options and getting template elements
         *
         * @since 6.17.0
         */
        initialize: function (options) {
            this.options = options;

            var self = this,
                o = self.options;

            self.searchString = o.searchString;
            self.context = o.context;

            self.renderedTemplate = self.template({
                searchString: self.searchString,
                additionalContent: o.additionalContent || undefined
            });

            $.extend(self, $.tmplItem(self.renderedTemplate).elements);

            self.collection.on('remove', function (model) {
                self.$('input[value=' + model.get('ObjectID') + ']').removeAttr('checked');
            });
        },

        /**
         * Resets the searchfeild (clearing the value, removing the ui-changed class and hiding the reset button)
         *
         * @since 6.17.0
         */
        resetSearchField: function () {
            this.searchField
                .val('')
                .removeClass('ui-changed');
            this.resetButton.addClass('Opacity0');
        },

        /**
         * Render tabs according to set options
         *
         * @since 6.17.0
         * @chainable
         * @return {Object} jQuery
         */
        render: function () {
            var self = this,
                o = self.options;

            self.$el.html(self.renderedTemplate);
            self.$('input').uiInput();

            if (self.searchField.val() === '') {
                this.resetButton.addClass('Opacity0');
            }

            self.additionalContent.find('input').on('click', function (event) {
                self.trigger('setAdditionalContentOptions', self.getAdditionalContent());
            });

            self.additionalContent.find('[data-js]').metaparse();

            // Showing and hiding the clearing cross and waiting for the user to hit return
            self.searchField.on('keyup', function (event) {
                // render on 'return'
                if (event.which === 13) {
                    //self.render();
                    self.trigger('search', self.searchField.val());
                }

                if (self.searchField.val() !== '') {
                    self.resetButton.removeClass('Opacity0');
                } else {
                    self.resetButton.addClass('Opacity0');
                }
            });

            // Clearing search field
            self.resetButton.on('click', function (event) {
                self.resetSearchField();
                self.trigger('search', undefined);
            });

            // Tell the main view that we're searching to render the results into a new view
            self.searchButton.on('click', function (event) {
                self.trigger('search', self.searchField.val());
            });

            self.table.uiDatatable({
                context: self.context,
                action: o.searchAction,
                parentObjectId: o.parentObjectId || undefined,
                searchString: self.searchField.val() === '' ? undefined : self.searchField.val(),
                otherParameters: o.searchOptions
            }).on('selectionstatechanged', function (event, item) {
                item.type = self.context;
                if ($(event.originalTarget).is(':checked')) {
                    self.collection.add(item);
                } else {
                    self.collection.remove(self.collection.findWhere({
                        'ObjectID': item.ObjectID
                    }));
                }
            }).on('pagechanged', function () {
                self.selectElements();
                self.checkRequiredHeight();
            }).on('changecontent', function (event, id) {
                self.trigger('changecontent', id, self.context);
            }).on('datatablerendered', function (event, data) {
                self.path.empty();
                if (data.path && !self.searchString) {
                    self.renderPath(data.path, 1);
                    self.path.find('a').on('click', function (event) {
                        self.trigger('changecontent', $(event.originalTarget).data('id'));
                    });
                } else if (self.searchString) {
                    self.path.append(dict.translate('SearchResults'));
                }
                // if we have no path we're not doing anything :)

                self.checkRequiredHeight();
                self.selectElements();
            });

            self.checkRequiredHeight();
            return self;
        },

        /*
         * render the path and crunches several elements recursively when it gets too large
         *
         * @since 6.17.0
         * @param  {Array} elements  [description]
         * @param  {Int} cropIndex [description]
         */
        renderPath: function (elements, cropIndex) {
            var self = this,
                path = '', //elements.length >= 2 ? ('<a href="javascript:void(\'back\');" data-id="' + elements[elements.length - 2].ObjectID + '"><=</a>&nbsp;|&nbsp;') : ('<=&nbsp;|&nbsp;'),
                MAX_PATH_LENGTH = 440;

            $.each(elements, function (i, elem) {
                path += (i !== elements.length - 1) ? ('<span class="BreadcrumbItem"><a href="javascript:void(\'navigate\');" data-id="' + elem.ObjectID + '"' + (elem.CrunchedName ? 'title="' + elem.NameOrAlias + '"' : '') + ' > ' + (elem.CrunchedName || elem.NameOrAlias) + '</a></span> ') : elem.NameOrAlias;
            });
            self.path.html(path);

            if (self.path.width() > MAX_PATH_LENGTH) {
                if (elements[cropIndex].NameOrAlias.length > 8) {
                    elements[cropIndex].CrunchedName = ep.scrunch(elements[cropIndex].NameOrAlias, 8);
                }

                if (cropIndex + 1 < elements.length) {
                    self.renderPath(elements, cropIndex + 1);
                }
            }
        },

        /*
         * Select (check) all elements (checkboxes) that are inside the collection
         *
         * @since 6.17.0
         */
        selectElements: function () {
            var self = this;

            self.collection.each(function (item) {
                self.$('input[value=' + item.get('ObjectID') + ']').prop('checked', true);
            });
        },

        /**
         * Fetches information about the additional content the view was provided with
         *
         * @since 6.17.0
         * @return {Object} 'id': 'property value'
         */
        getAdditionalContent: function () {
            var additionalContent = {};

            this.$('span.additional-content [name]').each(function () {
                var e = $(this);

                switch (e.prop('tagName')) {
                case 'INPUT':
                    switch (e.attr('type').toLowerCase()) {
                    case 'checkbox':
                        additionalContent[e.attr('name')] = e.prop('checked');
                        break;
                        // add "case 'other-type':" if you need it
                    }
                    // add "case 'other-tag-name':" if you need it
                    break;
                }
            });

            return additionalContent;
        },

        checkRequiredHeight: function () {
            var self = this;

            // we put this code in a timeout, because the browser should re-render the page before
            // executing this code.
            setTimeout(function () {
                var requiredHeight = self.$el.innerHeight();

                if (self.requiredHeight && self.requiredHeight === requiredHeight) {
                    return;
                }

                self.requiredHeight = requiredHeight;
                self.trigger('change:requiredHeight', requiredHeight);
            }, 0);
        }
    });
});