
#include "tool_mline.h"

#include "crosshair.h"
#include "data.h"
#include "obj_any.h"
#include "obj_line.h"
#include "obj_text.h"
#include <librnd/hid/hid.h>
#include <librnd/hid/hid_inlines.h>
#include <librnd/core/rnd_printf.h>
#include <librnd/core/misc_util.h>
#include <librnd/core/rnd_conf.h>
#include <math.h>

camv_tool_mline_t camv_tool_mline;

static void create_mline(rnd_design_t *hl)
{
	camv_any_obj_t *o;
	camv_design_t *camv = (camv_design_t *)hl;
	camv_layer_t *ly = camv_layer_by_name(camv, camv_measurement_layer_name, 1);
	double dist = rnd_distance(camv_tool_mline.x1, camv_tool_mline.y1, camv_tool_mline.x2, camv_tool_mline.y2);
	double scale;

	o = (camv_any_obj_t *)camv_line_new();
	o->line.x1 = camv_tool_mline.x1; o->line.y1 = camv_tool_mline.y1;
	o->line.x2 = camv_tool_mline.x2; o->line.y2 = camv_tool_mline.y2;
	o->line.thick = 1;
	camv_obj_add_to_layer(ly, o);

	o = (camv_any_obj_t *)camv_text_new();
	o->text.x = (camv_tool_mline.x1 + camv_tool_mline.x2) / 2;
	o->text.y = (camv_tool_mline.y1 + camv_tool_mline.y2) / 2;
	o->text.rot = atan2(camv_tool_mline.y2 - camv_tool_mline.y1, camv_tool_mline.x2 - camv_tool_mline.x1) * RND_RAD_TO_DEG;
	o->text.s = rnd_strdup_printf("%m+%.03$$mS", rnd_conf.editor.grid_unit->allow, (rnd_coord_t)dist);

	scale = log(dist/1000000.0);
	if (scale < 0) {
		scale = floor(dist/100000.0) / 100.0;
		if (scale < 0.0025)
			scale = 0.0025;
	}
	else if (scale < 1)
		scale = floor(scale)*0.8+0.2;
	else
		scale = floor(scale);

	o->text.scale = scale;
	o->text.thickness = scale/20.0;


	camv_text_update(hl, &o->text, ly);
	camv_obj_add_to_layer(ly, o);
}

static void tool_mline_init(void)
{
}

static void tool_mline_uninit(void)
{
}

static void tool_mline_press(rnd_design_t *hl)
{
}

static void tool_mline_release(rnd_design_t *hl)
{
	switch(camv_tool_mline.clicked) {
		case 0:
			camv_tool_mline.x1 = camv_tool_mline.x2 = camv.crosshair_x;
			camv_tool_mline.y1 = camv_tool_mline.y2 = camv.crosshair_y;
			camv_tool_mline.clicked = 1;
			break;
		case 1:
			camv_tool_mline.x2 = camv.crosshair_x;
			camv_tool_mline.y2 = camv.crosshair_y;
			create_mline(hl);
			camv_tool_mline.clicked = 0;
			break;
	}
}

static void tool_mline_adjust_attached_objects(rnd_design_t *hl)
{
	if (camv_tool_mline.clicked == 1) {
		camv_tool_mline.x2 = camv.crosshair_x;
		camv_tool_mline.y2 = camv.crosshair_y;
	}
}


static void tool_mline_draw_attached(rnd_design_t *hl)
{
	rnd_hid_set_line_cap(camv_crosshair_gc, rnd_cap_round);
	rnd_hid_set_line_width(camv_crosshair_gc, -1);

	switch(camv_tool_mline.clicked) {
		case 0: break;
		case 1:
			rnd_render->draw_line(camv_crosshair_gc, camv_tool_mline.x1, camv_tool_mline.y1, camv_tool_mline.x2, camv_tool_mline.y2);
			break;
	}
}

rnd_bool tool_mline_undo_act(rnd_design_t *hl)
{
	return 0;
}

rnd_bool tool_mline_redo_act(rnd_design_t *hl)
{
	return 0;
}



/* XPM */
static const char *mline_icon[] = {
/* columns rows colors chars-per-pixel */
"21 21 4 1",
"  c #000000",
". c #7A8584",
"X c #6EA5D7",
"O c None",
/* pixels */
"OOOO.OOOOOOOOOOOOOOOO",
"OOOO.OOOOOOOOOOOOOOOO",
"OOO.OOOOOOOOOOOOOOOOO",
"OOO.XXOOOOOOOOOOOOOOO",
"OOO.OOXXXOOOOOOOOO.OO",
"OO.OOOOOOXXXOOOOOO.OO",
"OO.OOOOOOOOOXXXOO.OOO",
"OOOOOOOOOOOOOOOXX.OOO",
"OOOOOOOOOOOOOOOOO.OOO",
"OOOOOOOOOOOOOOOO.OOOO",
"OOOOOOOOOOOOOOOO.OOOO",
"OOOOOOOOOOOOOOOOOOOOO",
"O OOO O OOO   O OOO O",
"O  O  O OOOO OO  OO O",
"O O O O OOOO OO  OO O",
"O OOO O OOOO OO O O O",
"O OOO O OOOO OO O O O",
"O OOO O OOOO OO OO  O",
"O OOO O OOOO OO OO  O",
"O OOO O   O   O OOO O",
"OOOOOOOOOOOOOOOOOOOOO"
};


static rnd_tool_t camv_rnd_tool_mline = {
	"mline", NULL, std_tools_cookie, 100, mline_icon, RND_TOOL_CURSOR_NAMED("pencil"), 0,
	tool_mline_init,
	tool_mline_uninit,
	tool_mline_press,
	tool_mline_release,
	tool_mline_adjust_attached_objects,
	tool_mline_draw_attached,
	tool_mline_undo_act,
	tool_mline_redo_act
};
