--- pallet_label_ferrum.lua
--
-- @module report

--[[
Sellaisen muutokset saist tehdä tarraan että toimitusosoite kentässä lukee asiakkaan nimi ja postitoimipaikka/maa.
Pois jäisi katuosoite, postinumero. Näin saataisiin tiedot mahtumaan kenttään.
]]
if not ... then
	package.path = "lib/?.lua;lib/?.lx;"..package.path
	package.path = "../lib/?.lua;../lib/?.lx;"..package.path
	require "start"
end

local util = require "util"
local pathMain = util.pathMain()
local peg = require "peg"
local l = require "lang".l
local draw = require "draw"
local printer = require "printer"
local json = require "json"
local callServer = require "call_server"

local prf = util.prf("report/dn/pallet_label/pallet_label.json")

local dotsPerInch = prf and prf.dots_per_inch or 600 -- 203 = Zebra, 600 = pdf and win xps
local printerName = prf and prf.printer_name or "Bullzip PDF Printer" -- "B-310N(Network)" -- "Bullzip PDF Printer" -- "Microsoft XPS Document Writer"

local function documentType(docType)
	if docType == "print_win" and not util.isWin() then
		docType = "pdf"
	elseif util.fromZbs() then
		docType = "pdf"
	end
	return docType
end
local docType = documentType("print_win") -- svg, pdf, png, print_win

local fileName = "report/pallet_label_ferrum"
local paperType = "A5 landscape" -- "A4 landscape"
local paper = {
	border_left = 20,
	border_top = 20,
	border_right = 20,
	border_bottom = 20,
}

local mmWidth = 200 -- mm = measured millimeter
local mmHeight = 120
local mmAddressWidth = 135
local mmAddressHeight = 75
local mmRowWidth = 145
local mmRowHeight = 11
local mmOrderNumberHeight = 40
local mmLogoHeight = 20 -- mmRowHeight
local paperWidth, paperHeight, addressHeight, rowHeight, addressWidth
local rowWidth, logoHeight, orderNumberHeight, bottom
-- local langInUse = "fi_fi" -- "fi_fi" en_us what language is in use
local mainTable = "dn"
local rowTable = {"por"}
local style

local function setPaper(paperType, docType, dotsPerInch)
	docType = documentType(docType)
	if docType == "png" then
		dotsPerInch = 200
	-- elseif docType == "print_win" then
		-- dotsPerInch = 203 -- 203 = Zebra, 600 = pdf and win xps
	end
	-- print(l("paperType %s, docType %s, dotsPerInch %d", paperType, docType, dotsPerInch))
	paper = draw.setPaper(paper, paperType, docType, dotsPerInch)
	-- paper dimensions to use

	-- paperBottom = draw.bottom(paper)
	-- paperRight = draw.right(paper)
	paperWidth = draw.width(paper)
	paperHeight = draw.height(paper)
	-- convert real millimeters to paper pixels
	addressHeight = math.floor(mmAddressHeight / mmHeight * paperHeight)
	rowHeight = math.floor(mmRowHeight / mmHeight * paperHeight)
	addressWidth = math.floor(mmAddressWidth / mmWidth * paperWidth)
	rowWidth = math.floor(mmRowWidth / mmWidth * paperWidth)
	logoHeight = math.floor(mmLogoHeight / mmHeight * paperHeight)
	orderNumberHeight = math.floor(mmOrderNumberHeight / mmHeight * paperHeight)
	bottom = math.floor(addressHeight + rowHeight * 4)

	do

		local default_text = {
			font_name = "Arial", -- "sans-serif", -- Arial, Helvetica, sans-serif must be with lowercase
			font_size = 12,
			fit_text = "height",
		}

		local default_pict = {
			-- rect will be drawn behind pict if style contains stroke_color or fill_color, easier to debug
			margin = draw.margin(4),
			scaling = "fit",
			horizontal_align = "center",
			vertical_align = "middle",

			-- stroke_color = {r=0.3, b=0.9, g=0.3, a=0.9}, -- "black",
			-- fill_color = {r=0.4, b=0.3, g=0.8, a=0.05},
			stroke_width = 3,
		}
		default_pict.margin.top = 8

		local default_line = {
			stroke_color = "black",
			stroke_width = 1.0,
		}

		local default_rect = {
			stroke_color = "black",
			-- fill_color = {r=0.4, b=0.3, g=0.8, a=0.05},
			stroke_width = 1.0,
		}

		local delivery_address_hdr = util.clone(default_text)
		delivery_address_hdr.margin = {}
		delivery_address_hdr.margin.left = 2

		local delivery_address = util.clone(delivery_address_hdr)
		delivery_address.font_size = 36
		delivery_address.margin.top = 2
		delivery_address.text_wrap = "word"
		-- delivery_address.margin.top = delivery_address.top + delivery_address_hdr.font_size

		local row_hdr = util.clone(default_text)
		row_hdr.vertical_align = "middle"
		row_hdr.margin = {}
		row_hdr.margin.left = 2

		local row = util.clone(row_hdr)
		row.margin.left = 60 -- math.floor(rowWidth/8)
		row.font_size = 16


		local sales_order_id_hdr = util.clone(delivery_address_hdr)
		local sales_order_id = util.clone(default_text)
		sales_order_id.font_size = 50
		sales_order_id.font_weight = "bold"
		sales_order_id.horizontal_align = "center"
		sales_order_id.vertical_align = "middle"

		local dispatch_hdr = util.clone(delivery_address_hdr)
		local dispatch = util.clone(default_text)
		dispatch.font_size = 42
		dispatch.horizontal_align = "center"
		dispatch.vertical_align = "middle"

		local number_of_pallets = util.clone(default_text)
		-- number_of_pallets.font_name = "serif"
		number_of_pallets.font_size = 60
		number_of_pallets.font_weight = "bold"
		number_of_pallets.horizontal_align = "center"
		number_of_pallets.vertical_align = "middle"
		local number_of_pallets_hdr = util.clone(number_of_pallets)
		number_of_pallets_hdr.font_size = 40
		number_of_pallets_hdr.font_weight = ""
		number_of_pallets_hdr.horizontal_align = "left"
		number_of_pallets_hdr.vertical_align = "middle"
		local number_of_pallets_total = util.clone(number_of_pallets)
		number_of_pallets_total.font_size = 30
		number_of_pallets_total.font_weight = "bold"
		number_of_pallets_total.horizontal_align = "center"
		number_of_pallets_total.vertical_align = "middle"


		local box_hdr = util.clone(default_text)
		box_hdr.margin = {
			left = 2,
			top = box_hdr.font_size -- draw.rowHeight(box_hdr),
		}

		local paper_rect = util.clone(default_rect)
		paper_rect.stroke_color = {r=0.0, b=0.9, g=0.0, a=0.9}

		local box2 = util.clone(box_hdr)
		box2.font_size = 28
		-- box2.margin.top = box_hdr.margin.top + box2.font_size

		local box1 = util.clone(box2)
		box1.font_size = 40
		-- box1.margin.top = box_hdr.margin.top + box1.font_size
		box1.font_weight = "bold"

		style = {
			default_line = default_line,
			default_rect = default_rect,
			default_pict = default_pict,
			default_text = default_text,

			paper_rect = paper_rect,
			row_hdr = row_hdr,
			row = row,
			dispatch_hdr = dispatch_hdr,
			dispatch = dispatch,
			box_hdr = box_hdr,
			box1 = box1,
			box2 = box2,
			delivery_address_hdr = delivery_address_hdr,
			delivery_address = delivery_address,
			sales_order_id_hdr = sales_order_id_hdr,
			sales_order_id = sales_order_id,
			number_of_pallets_hdr = number_of_pallets_hdr,
			number_of_pallets = number_of_pallets,
			number_of_pallets_total = number_of_pallets_total,
		}
	end
end
if not ... then
	setPaper(paperType, docType, dotsPerInch)
end

local language = {
	fi_fi = {
		por_total_price_hdr = "Tilaus yht.",
	},
	en_us = {
		por_total_price_hdr = "Order total",
	},
}
-- local lang = language[langInUse]

	local function content(pref)
		local element = {}
		local line = {
		{
			type = "default",
			x = 0,
			y = 0,
		},
		--[[{
			id = "paper_border",
			type = "rect",
			x = 0,
			y = 0,
			width = paperWidth,
			height = paperHeight,
			style = style.paper_rect,
		},]]
		{
			id = "outside_border",
			type = "rect",
			x = 0,
			y = 0,
			width = paperWidth,
			height = bottom,
			style = style.default_rect,
		},
		{
			id = "address_horizontal_line",
			type = "line",
			x = 0,
			y = addressHeight,
			x2 = paperWidth,
			y2 = addressHeight,
			style = style.default_line,
		},
		{
			id = "address_vertical_line",
			type = "line",
			x = addressWidth,
			y = 0,
			x2 = addressWidth,
			y2 = addressHeight,
			style = style.default_line,
		},
		{
			id = "row_vertical_line",
			type = "line",
			x = rowWidth,
			y = addressHeight,
			x2 = rowWidth,
			y2 = bottom,
			style = style.default_line,
		},
		{
			id = "order_number_horizontal_line",
			type = "line",
			x = addressWidth,
			y = orderNumberHeight,
			x2 = paperWidth,
			y2 = orderNumberHeight,
			style = style.default_line,
		},
		{
			id = "dn_mark_horizontal_line",
			type = "line",
			x = 0,
			y = addressHeight + rowHeight,
			x2 = rowWidth,
			y2 = addressHeight + rowHeight,
			style = style.default_line,
		},
		{
			id = "dn_customer_order_number_horizontal_line",
			type = "line",
			x = 0,
			y = addressHeight + rowHeight * 2,
			x2 = rowWidth,
			y2 = addressHeight + rowHeight * 2,
			style = style.default_line,
		},
		{
			id = "dn_your_reference_horizontal_line",
			type = "line",
			x = 0,
			y = addressHeight + rowHeight * 3,
			x2 = rowWidth,
			y2 = addressHeight + rowHeight * 3,
			style = style.default_line,
		},
		{
			id = "logo_above_horizontal_line",
			type = "line",
			x = rowWidth,
			y = paperHeight - logoHeight,
			x2 = paperWidth,
			y2 = paperHeight - logoHeight,
			style = style.default_line,
		}
	}
	element.line = line

	local header = {
		{
			type = "default",
			x = 0,
			y = 0,
		},
		{
			type = "default_text",
			style = style.default_text,
		},
		{
			id = "logo",
			type = "pict",
			x = rowWidth,
			y = bottom - logoHeight,
			width = paperWidth - rowWidth,
			height = logoHeight,
			source = pref.logo_path,
			style = style.default_pict,
		},
		{
			{
				{
					id = "sales_order_id_hdr",
					type = "text",
					x = addressWidth,
					y = 0,
					height = orderNumberHeight,
					width = paperWidth - addressWidth,
					text = "Til. Nro",
					style = style.sales_order_id_hdr,
				},
				{
					id = "sales_order_id",
					type = "text",
					x = addressWidth,
					y = 0,
					height = orderNumberHeight,
					width = paperWidth - addressWidth,
					--text = "sor_sales_order_id", --data
					style = style.sales_order_id,
				},
			},
			{
				{
					id = "dn_dispatch_hdr",
					type = "text",
					x = addressWidth,
					y = orderNumberHeight,
					height = addressHeight - orderNumberHeight,
					width = paperWidth - addressWidth,
					text = "Lähetyslista",
					style = style.dispatch_hdr,
				},
				{
					id = "dn_dispatch_note_id",
					type = "text",
					x = addressWidth,
					y = orderNumberHeight,
					height = addressHeight - orderNumberHeight,
					width = paperWidth - addressWidth,
					--text = "dn_dispatch", --data
					style = style.dispatch,
				},
			},
		},
		{
			{
				id = "dn_delivery_address_hdr",
				type = "text",
				x = 0,
				y = 0,
				height = addressHeight,
				width = addressWidth,
				text = "Toimitusosoite",
				style = style.delivery_address_hdr,
			},
			{
				id = "dn_delivery_address",
				type = "text",
				x = 0,
				y = 10,
				height = addressHeight,
				width = addressWidth,
				--text = "VastaanottajaÖÅÄƒ\nPostiosoite ÖÅÄƒƒƒƒ\nPostitoimipaikkaÖÅÄƒ 123456789",
				style = style.delivery_address,
			},
		}
	}
	element.header = header


	local row = {
		{
			{
				id = "dn_mark_hdr",
				type = "text",
				x = 0,
				y = addressHeight,
				width = rowWidth,
				height = rowHeight,
				text = "Merkki:",
				style = style.row_hdr,
			},
			{
				id = "dn_mark",
				type = "text",
				x = 0,
				y = addressHeight,
				width = rowWidth,
				height = rowHeight,
				-- text = "NAPA\nNAPA\nNAPA\nNAPA",
				style = style.row,
			},
		},
		{
			{
				id = "dn_customer_order_number_hdr",
				type = "text",
				x = 0,
				y = addressHeight  + rowHeight,
				width = rowWidth,
				height = rowHeight,
				text = "Til. Nro:",
				style = style.row_hdr,
			},
			{
				id = "dn_customer_order_number",
				type = "text",
				x = 0,
				y = addressHeight  + rowHeight,
				width = rowWidth,
				height = rowHeight,
				-- text = "dn_customer_order_number",
				style = style.row,
			},
		},
		{
			{
				id = "dn_your_reference_hdr",
				type = "text",
				x = 0,
				y = addressHeight  + rowHeight * 2,
				width = rowWidth,
				height = rowHeight,
				text = "Viite:",
				style = style.row_hdr,
			},
			{
				id = "dn_your_reference",
				type = "text",
				x = 0,
				y = addressHeight  + rowHeight * 2,
				width = rowWidth,
				height = rowHeight,
				-- text = "Jana Loza\nJana Loza",
				style = style.row,
			},
			{
				id = "company_name_hdr",
				type = "text",
				x = 0,
				y = addressHeight  + rowHeight * 3,
				width = rowWidth,
				height = rowHeight,
				text = "Tilaaja:",
				style = style.row_hdr,
			},
			{
				id = "company_name",
				type = "text",
				x = 0,
				y = addressHeight  + rowHeight * 3,
				width = rowWidth,
				height = rowHeight,
				style = style.row,
			},
		},
			{
				id = "copy",
				type = "text",
				x = rowWidth,
				y = addressHeight,
				width = math.floor((paperWidth - rowWidth) * 2 / 3),
				height = paperHeight - addressHeight - logoHeight,
				text = "__copy",
				style = style.number_of_pallets,
			},
			{
				id = "dn_number_of_pallets_hdr",
				type = "text",
				x = rowWidth + math.floor((paperWidth - rowWidth) * 2 / 3),
				y = addressHeight ,
				width = math.floor((paperWidth - rowWidth) * 2 / 5),
				height = paperHeight - addressHeight - logoHeight,
				text = "/",
				style = style.number_of_pallets_hdr,
			},
			{
				id = "copy_count",
				type = "text",
				x = rowWidth + math.floor((paperWidth - rowWidth) * 2 / 3),
				y = addressHeight ,
				width = math.floor((paperWidth - rowWidth) * 1 / 3),
				height = paperHeight - addressHeight - logoHeight,
				-- text = "dn_number_of_pallets",
				style = style.number_of_pallets_total,
			},
	}
	element.row = row
	return element
end

local function preference(style, language, option)
	local pref = {
		-- data = data,
		style = style,
		language = language,
		row = nil,
	}

	pref.main_table = mainTable
	pref.row_table = rowTable

	pref.document_type = documentType(docType)
	pref.paper = paper

	for key,val in pairs(option) do
		pref[key] = val
	end
	setPaper(paperType, pref.document_type, dotsPerInch)
	pref.content = content(pref)
	return pref
end

local arg = {...}
local printReport
if util.from4d() == false then
	printReport = function(data, option)
		data = data or util.getFile("report/"..mainTable.."_data.json")
		option = {} -- {logo_path = "preference/report/ferrum_logo.png"} -- option or {logo_path = "report/ferrum_logo.png"}
		if option.logo_name then
			--if pathMain == "" then -- from zbs or command line -- peg.find(option.logo_name, "report/") < 1 then
			--	option.logo_path = "report/"..option.logo_name
			--else
			option.logo_path = pathMain.."preference/report/"..option.logo_name -- option.logo_path = pathMain..option.logo_name
			--end
		else
			option.logo_path = pathMain.."preference/report/ferrum_logo.png"
		end
		local pref = preference(style, language, option)
		if not pref.printer_name or pref.printer_name == "" then
			pref.printer_name = printerName
		end
		if not pref.file_name or pref.file_name == "" then
			pref.file_name = fileName
		end
		local prefFileName = fileName..".json"
		-- util.writeFile(prefFileName, pref)
		pref.data = data
		local time = util.seconds()
		-- util.printTable(pref)
		local pictArr = draw.draw(pref)
		time = util.seconds(time)
		print(fileName.." generation time: "..util.seconds_to_clock(time,8))
		return pictArr
	end
	if #arg == 0 then
		local pictArr = printReport()
		for i, pict in ipairs(pictArr) do
			local printFileName = util.runPath()..fileName..i.."."..docType
			if pict then
				-- print(i..". picture size: "..#pict)
				util.writeFile(printFileName, pict)
			end
			util.openFile(pathMain..printFileName)
		end
	end
else
	printReport = function(data, option)
		-- print("logo name: "..option.logo_name)
		-- print("pathMain: "..pathMain)
		if option.logo_name then
			if pathMain == "" then -- from zbs or command line -- peg.find(option.logo_name, "report/") < 1 then
				option.logo_path = "report/"..option.logo_name
			else
				option.logo_path = pathMain.."preference/report/"..option.logo_name -- option.logo_path = pathMain..option.logo_name
			end
		else
			option.logo_path = pathMain.."preference/report/ferrum_logo.png"
		end
		-- util.printTable(option, "print option")
		-- util.printTable(data, "print data")
		local pictArr
		local debug = 0
		if util.from4d() then
			local plg = require "plugin_4d"
			debug = plg.getLongVariable("<>_lx_lDebug")
		end
		if debug > 0 then
			local printerName2 = option.print and option.print.printer_name
			util.print("pallet label printer name: '%s', version: '%s'", printerName2, option.version or "")
		end
		local documentType
		if option.version == "nc" then
			local connectPref = util.prf("db_connection_preference.json").tcp_call_nc_server
			if connectPref == nil then
				util.printWarning("db_connection_preference.json does not contain tag 'tcp_call_nc_server'")
				return
			end
			local param = {
				call_function = "/rest/nc/print/pallet-label-old",
				-- language = "fi_fi",
				-- organization_id = "fi_demo4d.demo",
				-- user_id = user_id, -- TODO: fix auth
				-- password = password,
				connect = connectPref,
				option = option,
				data = data
			}
			local callTime = util.seconds()
			local ret = callServer.call(param)
			local retJson = ret and json.fromJson(ret)
			if not retJson then
				util.printWarning("pallet label print, server call failed")
				return
			end
			retJson.call_time = util.seconds(callTime)
			pictArr = retJson.page -- returns 2 pages in an array, result times are from last rendering call
			retJson.page = nil
			if debug > 0 then
				util.printTable(retJson, "callServer.call: "..param.call_function)
			end
			if retJson.error then
				util.printWarning("pallet label print, server call error: '%s'", tostring(retJson.error))
				return
			end
			documentType = "pdf" -- option.document_type
			option.file_name = nil
		else
			local pref = preference(style, language, option)
			util.printTable(pref, "pallet pref")
			pref.data = data
			-- print("logo path: "..option.logo_path)
			-- util.printTable(pref, "draw.draw(pref)")
			pictArr = draw.draw(pref)
			-- util.print("report pictArr size: %d", pictArr and #pictArr or 0)
			documentType = draw.documentType(option.document_type)
		end
		-- util.print("report pictArr size: %d, documentType: '%s', option.file_name: '%s', option.document_type: '%s'", pictArr and #pictArr or 0, documentType, tostring(option.file_name), tostring(option.document_type))
		if option.file_name and util.isWin() then
			if pictArr and #pictArr > 0 then
				util.writeFile(util.runPath()..option.file_name, table.concat(pictArr))
			end
			-- print("wrote file: "..option.file_name)
			if (option.document_type == "pdf" or option.document_type == "png") and option.print.printer_name and option.print then
				-- print("ImageView_PrintTo")
				local app = 'start /B /WAIT "" rundll32'
				local args = 'c:\\windows\\system32\\shimgvw.dll,ImageView_PrintTo /pt "'..peg.replace(option.file_name, "/", "\\")..'" "'..option.print.printer_name..'"'
				local ok, ret = os.execute(app.." "..args) -- util.openApplication(app, args, "wait")
				if ok ~= true then
					print("print error:", ok, ret, app.." "..args)
				end
			end
		elseif documentType == "pdf" or documentType == "png" then
			util.print("option.print.printer_name: '%s'", option.print.printer_name)
		  if option.print and option.print.printer_name and option.print.printer_name ~= "" then
				local ret, err
				local printCount = option.print.copy_count or 1
				local docName = option.print.document_name or "Pallet Label"
				if pictArr == nil then
					pictArr = {}
				end
				for _ = 1, printCount do
					for i, pict in ipairs(pictArr) do
						-- util.print("report pict size: %d, option.print.printer_name: '%s', docName: '%s', option.document_type: '%s'", #pict, option.print.printer_name, docName.." "..i, tostring(option.document_type))
						ret, err = printer.printData(option.print.printer_name, pict, docName.." "..i, printCount, option.document_type)
						if err then
							print(l("printing error '%s', document '%s'", err, docName.." "..i))
							break
						end
					end
				end
				return pictArr, err or ret or ""
			elseif pictArr then
				for i, pict in ipairs(pictArr) do
					if pict then
						local printFileName = util.runPath()..fileName..i.."."..docType -- multiple labes are printed calling this method twice, so i is always 1
						print(pathMain..printFileName)
						util.writeFile(pathMain..printFileName, pict)
						util.openFile(pathMain..printFileName)
					end
				end
			end
		end
		return pictArr
	end
end

return {
	printReport = printReport
}