/*jshint scripturl:true*/
/* global google */
/* global visualizer */
/* global showNotice */
(function($, wpm, visualizer) {
	var libraryWidth, libraryHeight, wpmv, wpmV, wpmvv, wpmvvl, wpmvvb, l10n;

	wpmv = wpm.view;
	wpmV = wpm.View;
	wpmvv = wpmv.visualizer = {};
	l10n = wpmv.l10n.visualizer;

	/**
	 * =========================================================================
	 * COMMON
	 * =========================================================================
	 */

	if (!_.isFunction(wpmV.prototype.make)) {
		wpmV.prototype.make = function(tag, attrs, val) {
			var html, attr;

			html = '<' + tag;
			for (attr in attrs) {
				html += ' ' + attr + '="' + attrs[attr] + '"';
			}
			html += '>' + val + '</' + tag + '>';

			return html;
		};
	}

	wpmvv.Chart = wpmV.extend({
		className: 'visualizer-library-chart-canvas',

		constructor: function(options) {
			this.id = 'visualizer-chart-' + options.model.get('id');
			wpmV.apply(this, arguments);
		},

		render: function() {
			var self, model, chart;

			self = this;
			model = self.model;

			self.$el
				.width(self.options.width)
				.height(self.options.height)
				.css('background-image', 'none');

            chart = {};
			chart.type = model.get('type');
			chart.series = model.get('series');
			chart.data = model.get('data');
			chart.library = model.get('library');
			chart.settings = model.get('settings');
			chart.code = model.get('code');
			chart.settings.width = self.options.width;
			chart.settings.height = self.options.height;
            $('#' + self.id).parent().append(model.get('css'));

			if ( chart.library && 'd3' === chart.library ) {
				$('body').trigger('visualizer:render:chart:start', {
					id: self.id,
					charts: {
						[self.id]: {
							library: 'd3',
							code: chart.code,
							series: chart.series,
							data: chart.data
						}
					}
				});
			} else {
				$('body').trigger('visualizer:render:specificchart:start', {id: self.id, chart: chart, v: {page_type: 'post'}} );
			}
		}
	});

	/**
	 * =========================================================================
	 * LIBRARY
	 * =========================================================================
	 */

	wpmvvl = wpmvv.Library = wpmV.extend({
		id: 'visualizer-library-view',
		className: 'visualizer-clearfix',
		template: wpm.template('visualizer-library-empty'),

		initialize: function() {
			var self = this;

			_.defaults(self.options, {
				filter: 'all',
				page: 1
			});

			self.controller.on('visualizer:library:filter', self.onFilterChanged, self);
			self.controller.on('visualizer:library:page', self.onPageChanged, self);
			self.collection.on('reset', self.renderCollection, self);

			self.resetCollection();
		},

		onFilterChanged: function(filter) {
			this.options.filter = filter;
			this.options.page = 1;
			this.resetCollection();
		},

		onPageChanged: function(page) {
			this.options.page = page;
			this.resetCollection();
		},

		render: function() {},

		renderCollection: function() {
			var self = this;

			if (self.collection.length > 0) {
				self.$el.html('');
				self.collection.each(self.addChart, self);
			} else {
				self.$el.html(self.template({}));
			}
		},

		addChart: function(chart) {
			var self = this,
				view = new wpmvvl.Chart({ model: chart });

			self.$el.append(view.$el);
			self.views.set('#visualizer-chart-' + chart.get('id'), view, { silent: true });
			view.render();
		},

		resetCollection: function() {
			var self = this,
				controller = self.controller,
				content = controller.$el.find(controller.content.selector);

			content.lock();
			self.collection.fetch({
				silent: false,
				data: {
					filter: self.options.filter,
					page: self.options.page
				},
				statusCode: {
					200: function(response) {
						var paginationView = controller.toolbar.get('toolbar').get('pagination');

						if (self.options.page > response.total) {
							self.options.page = response.total;
							self.resetCollection();
						} else {
							paginationView.options.page = self.options.page;
							paginationView.options.total = response.total || 1;
							paginationView.render();
						}

						self.renderCollection();
                        if (self.collection.length > 0) {
                            $('.visualizer-library-chart').css('position', 'relative')
                                .append($(
                                    // jshint ignore:start
                                    '<div class="visualizer-chart-bg"></div>'
                                    + '<div class="visualizer-chart-insert-bg">'
                                    + '<button class="button button-primary visualizer-library-chart-insert">' + visualizer.i10n.insert + '</button>'
                                    + '</div>'
                                    // jshint ignore:end
                                ))
                                .on('mouseover', function(){
                                    $(this).addClass('hover');
                                });
                        }
						content.unlock();
					}
				}
			});
		}
	});

	wpmvvl.Chart = wpmV.extend({
		className: 'visualizer-library-chart',
		template: wpm.template('visualizer-library-chart'),

		events: {
			'click .visualizer-library-chart-delete': 'deleteChart',
			'click .visualizer-library-chart-insert': 'insertChart',
			'click .visualizer-library-chart-shortcode': 'selectShortcode'
		},

		initialize: function() {
			var self = this;

			if (!libraryWidth && !libraryHeight) {
				libraryWidth = $('#visualizer-library-view').width() / 3 - 40;
				libraryHeight = libraryWidth * 3 / 4;

				libraryWidth = Math.floor(libraryWidth);
				libraryHeight = Math.floor(libraryHeight);
			}

			self._view = new wpmvv.Chart({
				model: self.model,
				width: libraryWidth,
				height: libraryHeight
			});

			self.$el.html(self.template(self.model.toJSON())).prepend(self._view.$el);
			self.views.set('#' + self._view.id, self._view, { silent: true });
		},

		render: function() {
			this._view.render();
		},

		deleteChart: function() {
			var self = this;

			if (showNotice.warn()) {
				self.model.destroy({
					wait: true,
					success: function() {
						self.views.parent.resetCollection();
					}
				});
			}
		},

		insertChart: function() {
			wpm.editor.insert('[visualizer id="' + this.model.get('id') + '"]');
		},

		selectShortcode: function(e) {
			var range, selection;

			if (window.getSelection && document.createRange) {
				selection = window.getSelection();
				range = document.createRange();
				range.selectNodeContents(e.target);
				selection.removeAllRanges();
				selection.addRange(range);
			} else if (document.selection && document.body.createTextRange) {
				range = document.body.createTextRange();
				range.moveToElementText(e.target);
				range.select();
			}
		}
	});

	wpmvvl.Types = wpmV.extend({
		tagName: 'select',
		className: 'visualizer-library-filters',

		events: {
			change: 'onFilterChange'
		},

		initialize: function() {
			var self = this;

			self.createFilters();
			self.$el.html(_.chain(self.filters).map(function(filter) {
				return {
					el: self.make('option', {value: filter.key}, filter.text),
					priority: filter.priority || 50
				};
			}).sortBy('priority').pluck('el').value());
		},

		createFilters: function() {
			var self = this;

			self.filters = {};
			_.each(l10n.library.types, function(type, i) {
				self.filters[type] = {
					text: l10n.library.filters[type],
					key: type,
					priority: (i + 1) * 10
				};
			});
		},

		onFilterChange: function() {
			this.controller.trigger('visualizer:library:filter', this.el.value);
		}
	});

	wpmvvl.Pagination = wpmV.extend({
		id: 'visualizer-library-pagination',
		tagName: 'ul',

		events: {
			'click a.visualizer-library-pagination-page': 'onPageChange'
		},

		initialize: function() {
			_.defaults(this.options, {
				total: 1,
				page: 1
			});
		},

		render: function() {
			var self, items;

			self = this;
			if (self.options.page <= 1 && self.options.total <= 1) {
				self.$el.html('');
				return;
			}

			items = self._pagination(self.options.page, self.options.total, 7);

			self.$el.html(_.chain(items).map(function(item) {
				var content, className;

				content = item === '...' || item === self.options.page ? self.make('span', { class: 'visualizer-library-pagination-page' }, item) : self.make('a', { class: 'visualizer-library-pagination-page', href: 'javascript:;', 'data-page': item }, item);

				className = item === self.options.page ? 'visualizer-library-pagination-item visualizer-library-pagination-active' : 'visualizer-library-pagination-item';

				return self.make('li', { class: className }, content);
			}).value());
		},

		_pagination: function(current, total, max) {
			var i, tmp, pagenation = [];

			if ( total <= max ) {
				for ( i = 1; i <= total; i++ ) {
					pagenation.push(i);
				}
			} else {
				tmp = current - Math.floor( max / 2 );

				if ( max % 2 === 0 ) {
					tmp++;
				}

				if ( tmp < 1 ) {
					tmp = 1;
				}

				if ( tmp + max > total ) {
					tmp = total - max + 1;
				}

				for ( i = 1; i <= max; i++ ) {
					pagenation.push(tmp++);
				}

				if ( pagenation[0] !== 1 ) {
					pagenation[0] = 1;
					pagenation[1] = '...';
				}

				if ( pagenation[max - 1] !== total ) {
					pagenation[max - 1] = total;
					pagenation[max - 2] = '...';
				}
			}

			return pagenation;
		},

		onPageChange: function(e) {
			this.controller.trigger('visualizer:library:page', $(e.target).data('page'));
		}
	});
})(jQuery, wp.media, visualizer);

(function($) {
    $.fn.lock = function() {
        $(this).each(function() {
            var locker = $('<div class="locker"></div>'),
				loader = $('<div class="locker-loader"></div>'),
				$this = $(this),
				position = $this.css('position');

			if ($this.find('.locker').length > 0) {
				return;
			}

            if (!position) {
                position = 'static';
            }

			$this.css('overflow', 'hidden');
            switch(position) {
                case 'absolute':
                case 'relative':
                    break;
                default:
                    $this.css('position', 'relative');
                    break;
            }
            $this.data('position', position);

            locker.css('top', $this.scrollTop() + 'px').append(loader);
            $this.append(locker);
        });

        return $(this);
    };

    $.fn.unlock = function() {
        $(this).each(function() {
			var $this = $(this);

            $this.css({
				position: $this.data('position'),
				overflow: 'auto'
			}).find('.locker').remove();
        });

        return $(this);
    };
})(jQuery);
