class Dashboard {
  constructor(options) {
    this.options = $.extend({
			columnNumber : 1,
			lineNumber : 1,
			placeHolderPadding : 10
	},options);
    this.widgets = {};

    var grid  = '<div class="dashboard-grid" >';
	for(var u =0 ; u<options.lineNumber;u++){
		for(var i =0 ; i<options.columnNumber;i++){
			grid += '<div data-row="'+u+'" data-column="'+i+'" style="grid-row: '+(u+1)+" / "+(u+1)+";grid-column: "+(i+1)+" / "+(i+1)+';padding:'+this.options.placeHolderPadding+'px;" class="dashboard-placeholder"></div>';
		}
	}
	grid  += '</div>';
	this.grid = $(grid);
	this.options.element.addClass('dashboard-container');
	this.options.element.css({width:'100%',height:'1000px'});
	this.options.element.append(this.grid);
	this.widgetTemplate = $('#dashboard-widget-template').html();
	this.placeHolders = $('.dashboard-placeholder');
	this.triggers = [];
	

	var object = this;

	this.placeHolders.droppable({
	  tolerance : 'pointer',
      classes: {
        "ui-droppable-hover": 'drag-over'
      },
      drop: function( event, ui ) {
      	var data = $(this).data();
        var widgetId = ui.draggable.attr('data-id');
        object.widgets[widgetId].column = data.column;
        object.widgets[widgetId].row = data.row;
        object.renderPositions();
        object.trigger('move',object.widgetToArray(object.widgets[widgetId]));
      }
    });

	$(window).resize(function() {
	  	object.renderPositions();
	});

	$(window).mousemove(function(e){
		if(!object.resizing) return;
		$('.dashboard-widget').css('z-index','');
		object.resizing.element.css('z-index',1000);
		var objectPosition = object.resizing.element.position();
		object.resizing.element.css('width',(e.clientX - objectPosition.left)+'px');
		object.resizing.element.css('height',(e.clientY - objectPosition.top - 50)+'px');

	});
	$(window).mouseup(function(){
		if(!object.resizing) return;
		$('.dashboard-placeholder').removeClass('bordered');
		var firstPlaceHolder = object.placeHolders.eq(0);
		var placeholderWidth = firstPlaceHolder.outerWidth();
		var placeholderHeight = firstPlaceHolder.outerHeight();
		
		object.widgets[object.resizing.id].width = Math.round(object.resizing.element.outerWidth() / placeholderWidth);
		object.widgets[object.resizing.id].height = Math.round(object.resizing.element.outerHeight() / placeholderHeight);
		object.renderPositions();
		object.trigger('resize',object.widgetToArray(object.widgets[object.resizing.id]) );
		object.resizing = null;
	});

  }

  on(event,callback){
  	if(!this.triggers[event]) this.triggers[event] = [];
  	this.triggers[event].push(callback);
  	return this;
  }
  trigger(event,data){
  	if(!this.triggers[event]) return;
  	if(!data) data = {};
  	var abort = false;
  	for(var k in this.triggers[event]){
  		if(this.triggers[event][k](data) === true) abort = true;
  	}
  	return abort;
  }

  //Ajoute un ou plusieurs widgets
  addWidgets(widgets){
  	var object = this;
  	for(var k in widgets){
  		var widgetOptions = $.extend({
  			id : Math.floor(Math.random() * 100)+Date.now(),
  			draggable : true,
  			resizeable : true,
  			removable : true,
  			width: 1,
  			height : 1,
  			row : 0,
  			column :0,
  			options : [],
  			label : 'Sans titre',
  			content : "Aucun contenu"
  		},widgets[k]);
	  

  		widgetOptions.options.push({icon : 'fa fa-times', class:'widget-option-delete' , label : 'Supprimer' , click : function(element){ object.deleteWidget($(element).closest('.dashboard-widget').attr('data-id')); }});

	  	var widgetElement = $(object.widgetTemplate);
	  	widgetOptions.element = widgetElement;
	  	object.widgets[widgetOptions.id] = widgetOptions;
	  	object.grid.append(widgetElement);
	  	
		 	widgetElement.draggable(
		 		{ 
		 			handle: '.widget-header-title', 
		 			containment: object.grid,
		 			"ui-draggable-dragging" : "widget-dragging",
		 			start : function(event){
		 				
		 				var element = $(event.currentTarget);
		 				if(!element.hasClass('widget-draggable'))return false;

		 				$('.dashboard-widget').css('z-index','');
		 				element.css('z-index',1000);
		 			}
		 		}
		 	);
		 	widgetElement.find('.dashboard-widget-resize').mousedown(function(){
		 		var element = $(this).closest('.dashboard-widget');
		 		if(!element.hasClass('widget-resizeable'))return;
		 		object.resizing = object.widgets[element.attr('data-id')];
		 		$('.dashboard-placeholder').addClass('bordered');
		 	});
		 	widgetElement.find('.widget-option-delete').click(function(){
		 		object.deleteWidget($(this).closest('.dashboard-widget').attr('data-id'));
		 	});

		 	object.trigger('add',object.widgetToArray(widgetOptions));
	 	}


  	this.renderContents();
  	this.renderPositions();

  	
  }

  //Supprime un widget en fonctiond e son id
  deleteWidget(id){
  	var widget = this.widgets[id];
  	if(this.trigger('delete',this.widgetToArray(widget))) return;
  	this.widgets[id].element.remove();
  }

  widgetToArray(widget){
  	if(!widget) return {};
  	return {
		    id: widget.id,
		    draggable: widget.draggable,
		    resizeable: widget.resizeable,
		    removable: widget.removable,
		    width: widget.width,
		    height: widget.height,
		    row: widget.row,
		    column: widget.column,
		    label: widget.label,
		    content: widget.content,
		    icon: widget.icon,
		    headerBackground: widget.headerBackground
		};
  }

  //rafraichis le contenu des widgets en fonction du tableaud e widgets interne
  renderContents() {
	for(var k in this.widgets){
		var widget = this.widgets[k];
		if(widget.id) widget.element.attr('data-id',widget.id);
		if(widget.label !== null) widget.element.find('.widget-header-title').html(widget.label);
		if(widget.icon !== null) widget.element.find('.widget-header-icon i').attr('class',widget.icon);
		if(widget.options !== null){
			var tpl = '<li class="{{class}}" title="{{label}}"><i class="{{icon}}"></i></li>';
			widget.element.find('.widget-header-options').html('');
			for(var u in widget.options){
				var option = $(Mustache.render(tpl,widget.options[u]));
				
				if(widget.options[u].click){
					option.data('click',widget.options[u].click);
					option.click(function(){
						$(this).data('click')(this);
					});
				}
				widget.element.find('.widget-header-options').append(option);
			}
		}
		if(widget.headerBackground !== null) widget.element.find('.dashboard-widget-header').css('backgroundColor',widget.headerBackground);
		widget.element
		.toggleClass('widget-draggable',widget.draggable)
		.toggleClass('widget-resizeable',widget.resizeable)
		.toggleClass('widget-removable',widget.removable);
		if(widget.content !== null) widget.element.find('.dashboard-widget-content').html(widget.content);
	}
  }

  //resize / replace les wicgets en fonction de la taille de la fenetre et des cellules de grilles
  renderPositions() {
	var firstPlaceHolder = this.placeHolders.eq(0);
	var placeholderWidth = firstPlaceHolder.outerWidth();
	var placeholderHeight = firstPlaceHolder.outerHeight();

	for(var k in this.widgets){
		var widget = this.widgets[k];
		var cell = $('[data-row="'+widget.row+'"][data-column="'+widget.column+'"]').position();
		if(!cell) continue;
		widget.element.css({
			width  : ((widget.width * placeholderWidth)-(this.options.placeHolderPadding*2))+'px',
			height : ((widget.height * placeholderHeight)-(this.options.placeHolderPadding*2))+'px',
			top : (cell.top+this.options.placeHolderPadding)+'px',
			left : (cell.left+this.options.placeHolderPadding)+'px'
		});
	}
  }
}