package.cpath = package.cpath .. ";.\\?51.dll"

local iup = require("iuplua")
local utf8 = require("lua-utf8")
local u = utf8.escape

local version = "0.0.2"

local st = {
	multiline = "NO",
	expand = "YES",
	size = "24",
	mask = "[+/-]?(/d+/.?/d*|/./d+)",
}

local st_long = {
	multiline = "NO",
	expand = "NO",
	size = "80",
	mask = "[+/-]?(/d+/.?/d*|/./d+)",
}

local function attrib2number(value)
	if not value or value == "" then
		return 0
	else
		if value == "-" or value == "-0" then
			return 0
		else
			return tonumber(value)
		end
	end
end

local degree2minute = function(num)
	return num * 60
end

local minute2second = degree2minute

local second2minute = function(num)
	return num / 60.0
end

local minute2degree = second2minute

local second2rad = function(num)
	return num / 648000
end

local degree_dms = iup.text(st)
local minute_dms = iup.text(st)
local second_dms = iup.text(st)

local simple_degree = iup.text(st_long)
local simple_minute = iup.text(st_long)
local simple_second = iup.text(st_long)

local minutes_window = iup.hbox({
	iup.label({ title = u("Минут = ") }),
	simple_minute,
})

local degrees_window = iup.hbox({
	iup.label({ title = u("Градусов = ") }),
	simple_degree,
})

local seconds_window = iup.hbox({
	iup.label({ title = u("Секунд = ") }),
	simple_second,
})

local degree_minute_second_window = iup.hbox({
	iup.label({ title = u("Целая запись: ") }),
	iup.hbox({
		degree_dms,
		iup.label({ title = u("%x{B0}") }),
	}),
	iup.hbox({
		minute_dms,
		iup.label({ title = u("'") }),
	}),
	iup.hbox({
		second_dms,
		iup.label({ title = u('"') }),
	}),
	ngap = "10",
	alignment = "ACENTER",
})

local simple_rad_pi = iup.text(st_long)
local simple_rad_digit = iup.text(st_long)

local rad_winow = iup.hbox({
	iup.label({ title = u("Радианы:") }),
	iup.vbox({
		iup.hbox({ simple_rad_pi, iup.label({ title = u(" * Пи") }) }),
		iup.hbox({ simple_rad_digit }),
	}),
	ALIGNMENT = "ACENTER",
})

local main_window = iup.vbox({
	iup.hbox({
		iup.label({ title = "Degree converter\t\t\t" }),
		iup.label({ title = "Version = " .. version }),
	}),
	iup.vbox({
		degree_minute_second_window,
		degrees_window,
		minutes_window,
		seconds_window,
		rad_winow,
	}),
})

local dlg = iup.dialog({
	main_window,
	title = "Degree converter",
	margin = "10x10",
	resize = "NO",
})

local view_in_dms = function(sec)
	local second = sec % 60
	local raw = math.floor(sec / 60)
	local minute = raw % 60
	raw = math.floor(raw / 60)
	local degree = raw % 360
	return degree, minute, second
end

local view_out_dms = function(deg_str, min_str, sec_str)
	local second_in = attrib2number(sec_str)
	local minute_in = attrib2number(min_str)
	local degree_in = attrib2number(deg_str)

	local second_out, minute_out, degree_out = second_in, minute_in, degree_in

	if degree_in > 0 then
		second_out = second_out + degree_in * 3600
		minute_out = minute_out + degree_in * 60
	end

	if minute_in > 0 then
		second_out = second_out + minute_in * 60
		degree_out = degree_out + minute_in / 60
	end

	if second_in > 0 then
		degree_out = degree_out + second_in / 3600
		minute_out = minute_out + second_in / 60
	end

	return degree_out, minute_out, second_out
end

iup.SetGlobal("UTF8MODE", "YES")

dlg:showxy(iup.CENTER, iup.CENTER)

function simple_degree:valuechanged_cb()
	simple_minute.value = degree2minute(attrib2number(simple_degree.value))
	simple_second.value = minute2second(simple_minute.value)
	degree_dms.value, minute_dms.value, second_dms.value = view_in_dms(simple_second.value)
	simple_rad_pi.value = second2rad(simple_second.value)
	simple_rad_digit.value = math.rad(simple_second.value)
end

function simple_minute:valuechanged_cb()
	simple_degree.value = minute2degree(attrib2number(simple_minute.value))
	simple_second.value = minute2second(attrib2number(simple_minute.value))
	degree_dms.value, minute_dms.value, second_dms.value = view_in_dms(simple_second.value)
	simple_rad_pi.value = second2rad(simple_second.value)
	simple_rad_digit.value = math.rad(simple_second.value / 60 / 60)
end

function simple_second:valuechanged_cb()
	simple_minute.value = second2minute(attrib2number(self.value))
	simple_degree.value = minute2degree(simple_minute.value)
	degree_dms.value, minute_dms.value, second_dms.value = view_in_dms(attrib2number(self.value))
	simple_rad_pi.value = second2rad(attrib2number(self.value))
	simple_rad_digit.value = math.rad(attrib2number(self.value) / 60 / 60)
end

function degree_dms:valuechanged_cb()
	simple_degree.value, simple_minute.value, simple_second.value =
		view_out_dms(degree_dms.value, minute_dms.value, second_dms.value)
	simple_rad_pi.value = second2rad(simple_second.value)
	simple_rad_digit.value = math.rad(simple_degree.value)
end

function minute_dms:valuechanged_cb()
	simple_degree.value, simple_minute.value, simple_second.value =
		view_out_dms(degree_dms.value, minute_dms.value, second_dms.value)
	simple_rad_pi.value = second2rad(simple_second.value)
	simple_rad_digit.value = math.rad(simple_degree.value)
end

function second_dms:valuechanged_cb()
	simple_degree.value, simple_minute.value, simple_second.value =
		view_out_dms(degree_dms.value, minute_dms.value, second_dms.value)
	simple_rad_pi.value = second2rad(simple_second.value)
	simple_rad_digit.value = math.rad(simple_degree.value)
end

function simple_rad_pi:valuechanged_cb()
	simple_degree.value = attrib2number(self.value) * 180
	simple_minute.value = degree2minute(simple_degree.value)
	simple_second.value = minute2second(simple_minute.value)
	degree_dms.value, minute_dms.value, second_dms.value = view_in_dms(simple_second.value)
	simple_rad_digit.value = attrib2number(self.value) * math.pi
end

function simple_rad_digit:valuechanged_cb()
	simple_degree.value = math.deg(attrib2number(self.value))
	simple_minute.value = degree2minute(simple_degree.value)
	simple_second.value = minute2second(simple_minute.value)
	degree_dms.value, minute_dms.value, second_dms.value = view_in_dms(simple_second.value)
	simple_rad_pi.value = second2rad(simple_second.value)
end

if iup.MainLoopLevel() == 0 then
	iup.MainLoop()
	iup.Close()
end
