void TileMapEditor::_erase_points(const DVector<Vector2> p_points) {

	int len = p_points.size();
	DVector<Vector2>::Read pr = p_points.read();

	for (int i=0;i<len;i++) {

		_set_cell(pr[i], TileMap::INVALID_CELL);
	}
}
void TileMapEditor::_menu_option(int p_option) {

	switch(p_option) {

		case OPTION_BUCKET: {

			tool=TOOL_BUCKET;

			canvas_item_editor->update();
		} break;
		case OPTION_PICK_TILE: {

			tool=TOOL_PICKING;

			canvas_item_editor->update();
		} break;
		case OPTION_SELECT: {

			tool=TOOL_SELECTING;
			selection_active=false;

			canvas_item_editor->update();
		} break;
		case OPTION_DUPLICATE: {

			_update_copydata();

			if (selection_active) {
				tool=TOOL_DUPLICATING;

				canvas_item_editor->update();
			}
		} break;
		case OPTION_ERASE_SELECTION: {

			if (!selection_active)
				return;

			undo_redo->create_action("Erase Selection");
			for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) {
				for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) {

					_set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false, true);
				}
			}
			undo_redo->commit_action();

			selection_active=false;
			copydata.clear();

			canvas_item_editor->update();
		} break;
	}
}
void TileMapEditor::_fill_points(const DVector<Vector2> p_points, const Dictionary& p_op) {

	int len = p_points.size();
	DVector<Vector2>::Read pr = p_points.read();

	int id = p_op["id"];
	bool xf = p_op["flip_h"];
	bool yf = p_op["flip_v"];
	bool tr = p_op["transpose"];

	for (int i=0;i<len;i++) {

		_set_cell(pr[i], id, xf, yf, tr);
	}
}
bool TileMapEditor::forward_input_event(const InputEvent& p_event) {

	if (!node || !node->get_tileset().is_valid() || !node->is_visible())
		return false;

	Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
	Matrix32 xform_inv = xform.affine_inverse();

	switch(p_event.type) {

		case InputEvent::MOUSE_BUTTON: {

			const InputEventMouseButton &mb=p_event.mouse_button;

			if (mb.button_index==BUTTON_LEFT) {

				if (mb.pressed) {

					if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
						return false; //drag

					if (tool==TOOL_NONE) {

						if (mb.mod.shift) {

							if (mb.mod.control)
								tool=TOOL_RECTANGLE_PAINT;
							else
								tool=TOOL_LINE_PAINT;

							selection_active=false;
							rectangle_begin=over_tile;

							return true;
						}

						if (mb.mod.control) {

							tool=TOOL_PICKING;
							_pick_tile(over_tile);

							return true;
						}

						tool=TOOL_PAINTING;
					}

					if (tool==TOOL_PAINTING) {

						int id = get_selected_tile();

						if (id!=TileMap::INVALID_CELL) {

							tool=TOOL_PAINTING;

							paint_undo.clear();
							paint_undo[over_tile]=_get_op_from_cell(over_tile);

							_set_cell(over_tile, id, flip_h, flip_v, transpose);
						}
					} else if (tool==TOOL_PICKING) {

						_pick_tile(over_tile);
					} else if (tool==TOOL_SELECTING) {

						selection_active=true;
						rectangle_begin=over_tile;
					}

					return true;

				} else {

					if (tool!=TOOL_NONE) {

						if (tool==TOOL_PAINTING) {

							int id=get_selected_tile();

							if (id!=TileMap::INVALID_CELL && paint_undo.size()) {

								undo_redo->create_action(TTR("Paint TileMap"));
								for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

									Point2 p=E->key();
									undo_redo->add_do_method(node,"set_cellv",p,id,flip_h,flip_v,transpose);
									undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr);
								}
								undo_redo->commit_action();

								paint_undo.clear();
							}
						} else if (tool==TOOL_LINE_PAINT) {

							int id=get_selected_tile();

							if (id!=TileMap::INVALID_CELL) {

								undo_redo->create_action("Line Draw");
								for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

									_set_cell(E->key(), id, flip_h, flip_v, transpose, true);
								}
								undo_redo->commit_action();

								paint_undo.clear();

								canvas_item_editor->update();
							}
						} else if (tool==TOOL_RECTANGLE_PAINT) {

							int id=get_selected_tile();

							if (id!=TileMap::INVALID_CELL) {

								undo_redo->create_action("Rectangle Paint");
								for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) {
									for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) {

										_set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true);
									}
								}
								undo_redo->commit_action();

								canvas_item_editor->update();
							}
						} else if (tool==TOOL_DUPLICATING) {

							Point2 ofs = over_tile-rectangle.pos;

							undo_redo->create_action(TTR("Duplicate"));
							for (List<TileData>::Element *E=copydata.front();E;E=E->next()) {

								_set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true);
							}
							undo_redo->commit_action();

							copydata.clear();

							canvas_item_editor->update();

						} else if (tool==TOOL_SELECTING) {

							canvas_item_editor->update();

						} else if (tool==TOOL_BUCKET) {

							DVector<Vector2> points = _bucket_fill(over_tile);

							if (points.size() == 0)
								return false;

							Dictionary op;
							op["id"] = get_selected_tile();
							op["flip_h"] = flip_h;
							op["flip_v"] = flip_v;
							op["transpose"] = transpose;

							undo_redo->create_action("Bucket Fill");

							undo_redo->add_do_method(this, "_fill_points", points, op);
							undo_redo->add_undo_method(this, "_erase_points", points);

							undo_redo->commit_action();
						}

						tool=TOOL_NONE;

						return true;
					}
				}
			} else if (mb.button_index==BUTTON_RIGHT) {

				if (mb.pressed) {

					if (tool==TOOL_SELECTING || selection_active) {

						tool=TOOL_NONE;
						selection_active=false;

						canvas_item_editor->update();

						return true;
					}

					if (tool==TOOL_DUPLICATING) {

						tool=TOOL_NONE;
						copydata.clear();

						canvas_item_editor->update();

						return true;
					}

					if (tool==TOOL_NONE) {

						paint_undo.clear();

						Point2 local = node->world_to_map(xform_inv.xform(Point2(mb.x, mb.y)));

						if (mb.mod.shift) {

							if (mb.mod.control)
								tool=TOOL_RECTANGLE_ERASE;
							else
								tool=TOOL_LINE_ERASE;

							selection_active=false;
							rectangle_begin=local;
						} else {

							tool=TOOL_ERASING;

							paint_undo[local]=_get_op_from_cell(local);
							_set_cell(local, TileMap::INVALID_CELL);
						}

						return true;
					}

				} else {
					if (tool==TOOL_ERASING || tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) {

						if (paint_undo.size()) {
							undo_redo->create_action(TTR("Erase TileMap"));
							for (Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

								Point2 p=E->key();
								undo_redo->add_do_method(node,"set_cellv",p,TileMap::INVALID_CELL,false,false,false);
								undo_redo->add_undo_method(node,"set_cellv",p,E->get().idx,E->get().xf,E->get().yf,E->get().tr);
							}

							undo_redo->commit_action();
							paint_undo.clear();
						}

						if (tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) {
							canvas_item_editor->update();
						}

						tool=TOOL_NONE;

						return true;
					}
				}
			}
		} break;
		case InputEvent::MOUSE_MOTION: {

			const InputEventMouseMotion &mm=p_event.mouse_motion;

			Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y)));

			if (new_over_tile!=over_tile) {

				over_tile=new_over_tile;
				canvas_item_editor->update();
			}

			if (tool==TOOL_PAINTING) {

				int id = get_selected_tile();
				if (id!=TileMap::INVALID_CELL) {

					if (!paint_undo.has(over_tile)) {
						paint_undo[over_tile]=_get_op_from_cell(over_tile);
					}

					_set_cell(over_tile, id, flip_h, flip_v, transpose);

					return true;
				}
			}

			if (tool==TOOL_SELECTING) {

				_select(rectangle_begin, over_tile);

				return true;
			}

			if (tool==TOOL_LINE_PAINT || tool==TOOL_LINE_ERASE) {

				int id = get_selected_tile();
				bool erasing = (tool==TOOL_LINE_ERASE);

				if (erasing && paint_undo.size()) {

					for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

						_set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr);
					}
				}

				paint_undo.clear();

				if (id!=TileMap::INVALID_CELL) {

					Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y);

					for (int i=0;i<points.size();i++) {

						paint_undo[points[i]]=_get_op_from_cell(points[i]);

						if (erasing)
							_set_cell(points[i], TileMap::INVALID_CELL);
					}

					canvas_item_editor->update();
				}

				return true;
			}
			if (tool==TOOL_RECTANGLE_PAINT || tool==TOOL_RECTANGLE_ERASE) {

				_select(rectangle_begin, over_tile);

				if (tool==TOOL_RECTANGLE_ERASE) {

					if (paint_undo.size()) {

						for (Map<Point2i, CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

							_set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr);
						}
					}

					paint_undo.clear();

					for (int i=rectangle.pos.y;i<=rectangle.pos.y+rectangle.size.y;i++) {
						for (int j=rectangle.pos.x;j<=rectangle.pos.x+rectangle.size.x;j++) {

							Point2i tile = Point2i(j, i);
							paint_undo[tile]=_get_op_from_cell(tile);

							_set_cell(tile, TileMap::INVALID_CELL);
						}
					}
				}

				return true;
			}
			if (tool==TOOL_ERASING) {

				if (!paint_undo.has(over_tile)) {
					paint_undo[over_tile]=_get_op_from_cell(over_tile);
				}

				_set_cell(over_tile, TileMap::INVALID_CELL);

				return true;
			}
			if (tool==TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {

				_pick_tile(over_tile);

				return true;
			}
		} break;
		case InputEvent::KEY: {

			const InputEventKey &k = p_event.key;

			if (!k.pressed)
				break;

			if (k.scancode==KEY_ESCAPE) {

				if (tool==TOOL_DUPLICATING)
					copydata.clear();
				else if (tool==TOOL_SELECTING || selection_active)
					selection_active=false;

				tool=TOOL_NONE;

				canvas_item_editor->update();

				return true;
			}

			if (tool!=TOOL_NONE || !mouse_over)
				return false;

			if (k.scancode==KEY_DELETE) {

				_menu_option(OPTION_ERASE_SELECTION);

				return true;
			}

			if (k.mod.command) {

				if (k.scancode==KEY_F) {

					search_box->select_all();
					search_box->grab_focus();

					return true;
				}
				if (k.scancode==KEY_B) {

					tool=TOOL_SELECTING;
					selection_active=false;

					canvas_item_editor->update();

					return true;
				}
				if (k.scancode==KEY_D) {

					_update_copydata();

					if (selection_active) {
						tool=TOOL_DUPLICATING;

						canvas_item_editor->update();

						return true;
					}
				}
			} else {

				if (k.scancode==KEY_A) {

					flip_h=!flip_h;
					mirror_x->set_pressed(flip_h);
					canvas_item_editor->update();
					return true;
				}
				if (k.scancode==KEY_S) {

					flip_v=!flip_v;
					mirror_y->set_pressed(flip_v);
					canvas_item_editor->update();
					return true;
				}
			}
		} break;
	}

	return false;
}
bool TileMapEditor::forward_input_event(const InputEvent& p_event) {

	if (!node || !node->get_tileset().is_valid())
		return false;

	Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
	Matrix32 xform_inv = xform.affine_inverse();
	Vector2 snap = node->get_cell_size();


	switch(p_event.type) {

		case InputEvent::MOUSE_BUTTON: {

			const InputEventMouseButton &mb=p_event.mouse_button;

			if (mb.button_index==BUTTON_LEFT) {


				if (mb.pressed && tool==TOOL_DUPLICATING) {


					List<_TileMapEditorCopyData> dupdata;
					Point2 ofs = over_tile-selection.pos;

					for(int i=selection.pos.y;i<=selection.pos.y+selection.size.y;i++) {

						for(int j=selection.pos.x;j<=selection.pos.x+selection.size.x;j++) {

							_TileMapEditorCopyData tcd;
							tcd.pos=Point2i(j,i);
							tcd.cell=node->get_cell(j,i);
							tcd.flip_h=node->is_cell_x_flipped(j,i);
							tcd.flip_v=node->is_cell_y_flipped(j,i);
							tcd.transpose=node->is_cell_transposed(j,i);
							dupdata.push_back(tcd);


						}
					}

					undo_redo->create_action("Duplicate");
					for (List<_TileMapEditorCopyData>::Element *E=dupdata.front();E;E=E->next()) {


						_set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true);
					}
					undo_redo->commit_action();

					tool=TOOL_NONE;
					canvas_item_editor->update();
					selection.pos=over_tile;

				} else if (mb.pressed && tool==TOOL_NONE) {

					if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
						return false; //drag
					if (mb.mod.shift) {

						tool=TOOL_SELECTING;
						selection_begin =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y)));
						selection.pos=selection_begin;
						selection.size=Point2(0,0);
						selection_active=true;
						canvas_item_editor->update();
						return true;

					} else if (mb.mod.control) {
						tool=TOOL_PICKING;
						set_selected_tile(node->get_cell(over_tile.x, over_tile.y));
						mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y));
						mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y));
						transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y));
						_update_transform_buttons();
						canvas_item_editor->update();
						return true;
					} else {
						int id = get_selected_tile();
						if (id!=TileMap::INVALID_CELL) {
							tool=TOOL_PAINTING;
							Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y))));
							paint_undo.clear();
							paint_undo[local]=_get_op_from_cell(local);
							node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
							return true;
						}
					}
				} else {

					if (tool==TOOL_PAINTING || tool == TOOL_SELECTING || tool == TOOL_PICKING) {

						if (tool==TOOL_PAINTING) {

							if (paint_undo.size()) {
								undo_redo->create_action("Paint TileMap");
								for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

									Point2i p=E->key();
									undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
									undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
								}

								undo_redo->commit_action();
								paint_undo.clear();
							}
						}
						tool=TOOL_NONE;
						return true;
					}
				}
			}

			if (mb.button_index==BUTTON_RIGHT) {

				if (mb.pressed && tool==TOOL_DUPLICATING) {

					tool=TOOL_NONE;
					canvas_item_editor->update();
				} else if (mb.pressed && tool==TOOL_NONE) {

					tool=TOOL_ERASING;
					Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y)));
					paint_undo.clear();
					paint_undo[local]=_get_op_from_cell(local);
					//node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
					//return true;
					_set_cell(local,TileMap::INVALID_CELL);
					return true;
				} else {

					if (tool==TOOL_ERASING) {

						if (paint_undo.size()) {
							undo_redo->create_action("Erase TileMap");
							for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {

								Point2i p=E->key();
								//undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
								_set_cell(p,TileMap::INVALID_CELL,false,false,false,true);
								undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
							}

							undo_redo->commit_action();
							paint_undo.clear();

						}
						tool=TOOL_NONE;
						return true;
					}
				}
			}

		} break;
		case InputEvent::MOUSE_MOTION: {

			const InputEventMouseMotion &mm=p_event.mouse_motion;

			Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y)));//(xform_inv.xform(Point2(mm.x,mm.y))/snap).floor();
			if (new_over_tile!=over_tile) {

				over_tile=new_over_tile;
				canvas_item_editor->update();
			}



			if (tool==TOOL_PAINTING) {

				int id = get_selected_tile();
				if (id!=TileMap::INVALID_CELL) {

					if (!paint_undo.has(over_tile)) {

						paint_undo[over_tile]=_get_op_from_cell(over_tile);
					}
					node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());

					return true;
				}
			}

			if (tool==TOOL_SELECTING) {

				Point2i begin=selection_begin;
				Point2i end =over_tile;

				if (begin.x > end.x) {

					SWAP( begin.x, end.x);
				}
				if (begin.y > end.y) {

					SWAP( begin.y, end.y);
				}

				selection.pos=begin;
				selection.size=end-begin;
				canvas_item_editor->update();

				return true;

			}

			if (tool==TOOL_ERASING) {
				Point2i local =over_tile;
				if (!paint_undo.has(over_tile)) {
					paint_undo[over_tile]=_get_op_from_cell(over_tile);
				}
				//node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
				_set_cell(local,TileMap::INVALID_CELL);
				return true;
			}

			if (tool==TOOL_PICKING) {
				set_selected_tile(node->get_cell(over_tile.x, over_tile.y));
				mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y));
				mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y));
				transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y));
				_update_transform_buttons();
				canvas_item_editor->update();
				return true;
			}

		} break;
		case InputEvent::KEY: {

			const InputEventKey &k = p_event.key;
			if (!node)
				break;

			if (k.pressed && k.scancode==KEY_DELETE && selection_active && tool==TOOL_NONE) {

				undo_redo->create_action("Delete");
				for(int i=selection.pos.y;i<=selection.pos.y+selection.size.y;i++) {

					for(int j=selection.pos.x;j<=selection.pos.x+selection.size.x;j++) {


						_set_cell(Point2i(j,i),TileMap::INVALID_CELL);
					}
				}
				undo_redo->commit_action();

				selection_active=false;
				canvas_item_editor->update();
				return true;
			}

			if (mouse_over && k.pressed && k.scancode==KEY_A  && tool==TOOL_NONE && !k.mod.command) {

				/*int cell = node->get_cell(over_tile.x,over_tile.y);
				if (cell!=TileMap::INVALID_CELL) {
					bool flip_h = node->is_cell_x_flipped(over_tile.x,over_tile.y);
					bool flip_v = node->is_cell_y_flipped(over_tile.x,over_tile.y);
					_set_cell(over_tile,cell,!flip_h,flip_v);
				}*/

				mirror_x->set_pressed( ! mirror_x->is_pressed() );
				canvas_item_editor->update();
				return true;
			}
			if (mouse_over && k.pressed && k.scancode==KEY_S  && tool==TOOL_NONE && !k.mod.command) {


				/*
				int cell = node->get_cell(over_tile.x,over_tile.y);
				if (cell!=TileMap::INVALID_CELL) {

					bool flip_h = node->is_cell_x_flipped(over_tile.x,over_tile.y);
					bool flip_v = node->is_cell_y_flipped(over_tile.x,over_tile.y);
					_set_cell(over_tile,cell,flip_h,!flip_v);
				}*/

				mirror_y->set_pressed( ! mirror_y->is_pressed() );
				canvas_item_editor->update();
				return true;
			}

			if (mouse_over && selection_active && k.pressed && k.mod.command && k.scancode==KEY_D && tool==TOOL_NONE) {

				tool=TOOL_DUPLICATING;
				canvas_item_editor->update();
				return true;
			}



		} break;
	}

	return false;
}