text: import app from './../app.js';
  import config from './../config.js';
  import Base_tools_class from './../core/base-tools.js';
  import Base_layers_class from './../core/base-layers.js';
  import Base_selection_class from './../core/base-selection.js';
  import GUI_tools_class from './../core/gui/gui-tools.js';
  import Helper_class from './../libs/helpers.js';
  import alertify from './../../../node_modules/alertifyjs/build/alertify.min.js';
  
  var instance = null;
  
  class Selection_class extends Base_tools_class {
  
  	constructor() {
  		super();
  
  		//singleton
  		if (instance) {
  			return instance;
  		}
  		instance = this;
  
  		var _this = this;
  
  		this.Base_layers = new Base_layers_class();
  		this.Helper = new Helper_class();
  		this.name = 'selection';
  		this.type = null;
  		this.selection_coords_from = null;
  		this.selection = {
  			x: null,
  			y: null,
  			width: null,
  			height: null,
  		};
  
  		var sel_config = {
  			enable_background: true,
  			enable_borders: true,
  			enable_controls: false,
  			enable_rotation: false,
  			enable_move: false,
  			data_function: function () {
  				return _this.selection;
  			},
  		};
  		this.mousedown_selection = null;
  		this.Base_selection = new Base_selection_class(sel_config, this.name);
  		this.GUI_tools = new GUI_tools_class();
  	}
  
  	load() {
  		var _this = this;
  
  		//mouse events
  		document.addEventListener('mousedown', function (event) {
  			_this.dragStart(event);
  		});
  		document.addEventListener('mousemove', function (event) {
  			_this.dragMove(event);
  		});
  		document.addEventListener('mouseup', function (event) {
  			_this.dragEnd(event);
  		});
  
  		// collect touch events
  		document.addEventListener('touchstart', function (event) {
  			_this.dragStart(event);
  		});
  		document.addEventListener('touchmove', function (event) {
  			_this.dragMove(event);
  		});
  		document.addEventListener('touchend', function (event) {
  			_this.dragEnd(event);
  		});
  
  		document.addEventListener('keydown', (e) => {
  			var code = e.keyCode;
  			if (this.Helper.is_input(e.target))
  				return;
  
  			if (code == 27) {
  				//escape
  				app.State.do_action(new app.Actions.Bundle_action('clear_selection', 'Clear Selection', this.on_leave()));
  			}
  			if (code == 46) {
  				//delete
  				if (config.TOOL.name == this.name) {
  					this.delete_selection();
  				}
  			}
  			if (code == 65 && (e.ctrlKey == true || e.metaKey)) {
  				//A
  				e.preventDefault();
  				this.select_all();
  			}
  		}, false);
  	}
  
  	dragStart(event) {
  		var _this = this;
  		if (config.TOOL.name != _this.name)
  			return;
  		_this.mousedown(event);
  	}
  
  	dragMove(event) {
  		var _this = this;
  		if (config.TOOL.name != _this.name)
  			return;
  		_this.mousemove(event);
  	}
  
  	dragEnd(event) {
  		var _this = this;
  		if (config.TOOL.name != _this.name)
  			return;
  		_this.mouseup(event);
  	}
  
  	mousedown(e) {
  		var mouse = this.get_mouse_info(e);
  		var layer = config.layer;
  		if (this.Base_selection.is_drag == false || mouse.click_valid == false)
  			return;
  
  		if (config.layer.type != 'image') {
  			alertify.error('This layer must contain an image. Please convert it to raster to apply this tool.');
  			return;
  		}
  
  		this.mousedown_selection = JSON.parse(JSON.stringify(this.selection));
  
  		if (this.selection.width != null && this.selection.height != null
  			&& mouse.x > this.selection.x
  			&& mouse.x < this.selection.x + this.selection.width
  			&& mouse.y > this.selection.y
  			&& mouse.y < this.selection.y + this.selection.height
  			&& layer.width == layer.width_original && layer.height == layer.height_original
  			) {
  			//move
  			this.type = 'move';
  		}
  		else {
  			//create new selection
  			this.selection = {
  				x: mouse.x,
  				y: mouse.y,
  				width: 0,
  				height: 0,
  			};
  			this.type = 'create';
  			this.selection_coords_from = {x: mouse.x, y: mouse.y};
  		}
  	}
  
  	mousemove(e) {
  		var mouse = this.get_mouse_info(e);
  		if (this.Base_selection.is_drag == false || mouse.is_drag == false)
  			return;
  		if (e.type == 'mousedown' && (mouse.click_valid == false) || config.layer.type != 'image') {
  			return;
  		}
  		if (this.selection_coords_from === null) {
  			return;
  		}
  		if (this.type == 'create') {
  			//create new selection
  			this.selection.width = mouse.x - mouse.click_x;
  			this.selection.height = mouse.y - mouse.click_y;
  			config.need_render = true;
  		}
  	}
  
  	mouseup(e) {
  		var mouse = this.get_mouse_info(e);
  
  		if (!this.Base_selection.is_drag) {
  			return;
  		}
  		if ((e.type == 'mousedown' && mouse.click_valid == false) || config.layer.type != 'image') {
  			return;
  		}
  		if (this.type === 'move') {
  			return; // Translate appears to not work at the moment
  		}
  
  		var width = mouse.x - this.selection.x;
  		var height = mouse.y - this.selection.y;
  
  		if (width == 0 || height == 0) {
  			//cancel selection
  			app.State.do_action(
  				new app.Actions.Bundle_action('clear_selection', 'Clear Selection', this.on_leave())
  			);
  			return;
  		}
  
  		if (this.selection.width != null && this.selection.height != null) {
  			//make sure coords not negative
  			var details = this.selection;
  			var x = details.x;
  			var y = details.y;
  			if (details.width < 0) {
  				x = x + details.width;
  				this.selection_coords_from.x = x;
  			}
  			if (details.height < 0) {
  				y = y + details.height;
  				this.selection_coords_from.y = y;
  			}
  			this.selection = {
  				x: x,
  				y: y,
  				width: Math.abs(details.width),
  				height: Math.abs(details.height),
  			};
  			app.State.do_action(
  				new app.Actions.Set_selection_action(this.selection.x, this.selection.y, this.selection.width, this.selection.height, this.mousedown_selection)
  			);
  		}
  	}
  
  	select_all() {
  		if (config.layer.type != 'image') {
  			alertify.error('This layer must contain an image. Please convert it to raster to apply this tool.');
  			return;
  		}
  		let actions = [];
  
  		if (config.TOOL.name != this.name) {
  			actions.push(
  				new app.Actions.Activate_tool_action(this.name)
  			);
  		}
  		actions.push(
  			new app.Actions.Set_selection_action(0, 0, config.WIDTH, config.HEIGHT, this.selection)
  		);
  		app.State.do_action(
  			new app.Actions.Bundle_action('select_all', 'Select All', actions)
  		);
  	}
  
  	render(layer) {
  		//nothing
  	}
  
  	delete_selection() {
  		var selection = this.selection;
  		var layer = config.layer;
  
  		if (config.layer.type != 'image') {
  			alertify.error('This layer must contain an image. Please convert it to raster to apply this tool.');
  			return;
  		}
  
  		if (selection == null) {
  			alertify.error('Nothing is selected.');
  			return;
  		}
  
  		app.State.do_action(
  			new app.Actions.Bundle_action('delete_selection', 'Delete Selection', [
  				new app.Actions.Reset_selection_action(this.selection)
  			])
  		);
  
  		delete config.layer.link_canvas;
  	}
  
  	on_leave() {
  		let actions = [
  			new app.Actions.Reset_selection_action(this.selection)
  		];
  		delete config.layer.link_canvas;
  		return actions;
  	}
  
  	clear_selection() {
  		app.State.do_action(
  			new app.Actions.Bundle_action('clear_selection', 'Clear Selection', this.on_leave())
  		);
  	}
  }
  ;
  export default Selection_class;
  