
local app_args = {...}
local appFrame = win.create_app_frame ()


local APP_TITLE         = "Banking"

local ID_OK             = 1

local ID_MENUBTN        = 101
local ID_BALANCE        = 102
local ID_CHANGEPIN      = 103
local ID_TRANSFER       = 104
local ID_MESSAGES       = 105

local ID_TRANSFROM      = 201
local ID_TRANSTO        = 202
local ID_TRANSAMOUNT    = 203
local ID_TRANSPIN       = 204

local ID_PINACC         = 301
local ID_PINOLD         = 302
local ID_PINNEW         = 303
local ID_PINCONFIRM     = 304

local ID_BALACC         = 401
local ID_BALPIN         = 402

local IDM_BALANCE       = 1001
local IDM_CHANGEPIN     = 1002
local IDM_TRANSFER      = 1003
local IDM_CLRMSGS       = 1004
local IDM_QUITAPP       = 1005

local ID_BANKING_FRAME  = 7863



-- balanceDlg --------------------------------------------------------
local balanceDlg = win.popupFrame:base()



function balanceDlg:on_create (name)
	self:dress ("Balance")

	self.bal_acc = win.inputWindow:new (self, ID_BALACC, 1, 2, 20, name, "Account")
	self.bal_pin = win.inputWindow:new (self, ID_BALPIN, 1, 4, 20, nil, "Pin")
	win.buttonWindow:new (self, ID_OK, 17, 6, " Ok ")

	self.bal_pin:set_mask_char ("*")

	if name then
		self.bal_pin:set_focus ()
	else
		self.bal_acc:set_focus ()
	end

	self:move (nil, nil, 22, 8)

	return true
end



function balanceDlg:on_event (event, p1, p2, p3, p4, p5)
	if event == "btn_click" then
		if p1:get_id () == ID_OK then
			if self.bal_acc:get_text ():len () < 1 then
				self.bal_acc:set_error (true)
				self.bal_acc:set_focus ()
			else
				self:close (ID_OK)
			end

			return true
		end
	end

	return false
end



function balanceDlg:on_child_focus (child, blurred)
	if win.popupFrame.on_child_focus (self, child, blurred) then
		return true
	end

	if child.set_sel then
		child:set_sel (0, -1, false)
	end
end



function balanceDlg:on_child_blur (child, focused)
	if win.popupFrame.on_child_blur (self, child, focused) then
		return true
	end

	if child.set_sel then
		child:set_sel (0, 0, false)
	end
end

-- end balanceDlg ----------------------------------------------------



-- changePinDlg --------------------------------------------------------
local changePinDlg = win.popupFrame:base()



function changePinDlg:on_create (name)
	self:dress ("Change Pin")

	self.pin_acc = win.inputWindow:new (self, ID_PINACC, 1, 2, 20, name, "Account")
	self.pin_old = win.inputWindow:new (self, ID_PINOLD, 1, 4, 20, nil, "Pin")
	self.pin_new = win.inputWindow:new (self, ID_PINNEW, 1, 6, 20, nil, "New Pin")
	self.pin_confirm = win.inputWindow:new (self, ID_PINCONFIRM, 1, 8, 20, nil, "Confirm")
	win.buttonWindow:new (self, ID_OK, 17, 10, " Ok ")

	self.pin_old:set_mask_char ("*")
	self.pin_new:set_mask_char ("*")
	self.pin_confirm:set_mask_char ("*")

	if name then
		self.pin_old:set_focus ()
	else
		self.pin_acc:set_focus ()
	end

	self:move (nil, nil, 22, 12)

	return true
end



function changePinDlg:on_event (event, p1, p2, p3, p4, p5)
	if event == "btn_click" then
		if p1:get_id () == ID_OK then
			if self.pin_acc:get_text ():len () < 1 then
				self.pin_acc:set_error (true)
				self.pin_acc:set_focus ()
			elseif self.pin_new:get_text ():len () ~= self.pin_confirm:get_text ():len () then
				self.pin_confirm:set_error (true)
				self.pin_confirm:set_focus ()
			else
				self:close (ID_OK)
			end

			return true
		end
	end

	return false
end



function changePinDlg:on_child_focus (child, blurred)
	if win.popupFrame.on_child_focus (self, child, blurred) then
		return true
	end

	if child.set_sel then
		child:set_sel (0, -1, false)
	end
end



function changePinDlg:on_child_blur (child, focused)
	if win.popupFrame.on_child_blur (self, child, focused) then
		return true
	end

	if child.set_sel then
		child:set_sel (0, 0, false)
	end
end

-- end changePinDlg ----------------------------------------------------


-- transferDlg ---------------------------------------------------------
local transferDlg = win.popupFrame:base()



function transferDlg:on_create (from, to)
	self:dress ("Transfer")

	self.trans_from = win.inputWindow:new (self, ID_TRANSFROM, 1, 2, 20, from, "From")
	self.trans_pin = win.inputWindow:new (self, ID_TRANSPIN, 1, 4, 20, nil, "Pin")
	self.trans_to = win.inputWindow:new (self, ID_TRANSTO, 1, 6, 20, to, "To")
	self.trans_amount = win.inputWindow:new (self, ID_TRANSAMOUNT, 1, 8, 8, nil, "Amount")
	win.buttonWindow:new (self, ID_OK, 17, 8, " Ok ")

	self.trans_pin:set_mask_char ("*")

	if from then
		self.trans_to:set_focus ()
	elseif to then
		self.trans_amount:set_focus ()
	else
		self.trans_from:set_focus ()
	end

	self:move (nil, nil, 22, 10)

	return true
end



function transferDlg:on_event (event, p1, p2, p3, p4, p5)
	if event == "btn_click" then
		if p1:get_id () == ID_OK then
			if self.trans_from:get_text ():len() < 1 then
				self.trans_from:set_error (true)
				self.trans_from:set_focus ()
			elseif self.trans_to:get_text ():len() < 1 then
				self.trans_to:set_error (true)
				self.trans_to:set_focus ()
			elseif not tonumber(self.trans_amount:get_text ()) then
				self.trans_amount:set_error (true)
				self.trans_amount:set_focus ()
			else
				self:close (ID_OK)
			end

			return true
		end
	end

	return false
end



function transferDlg:on_child_focus (child, blurred)
	if win.popupFrame.on_child_focus (self, child, blurred) then
		return true
	end

	if child.set_sel then
		child:set_sel (0, -1, false)
	end
end



function transferDlg:on_child_blur (child, focused)
	if win.popupFrame.on_child_blur (self, child, focused) then
		return true
	end

	if child.set_sel then
		child:set_sel (0, 0, false)
	end
end

-- end transferDlg -----------------------------------------------------



function appFrame:on_receive (msg)
	if msg.application == self.app_id and type (msg.data) == "table" then
		if msg.context == "bank_approved" or msg.context == "bank_declined" then
			if msg.data.message then
				self.app_messages:set_text (self.app_messages:get_text ().."\n\n"..msg.data.message)
				local x, y = self.app_messages:get_scroll_size ()
				self.app_messages:set_scroll_org (0, y)

				return true
			end
		end
	end

	return false
end



function appFrame:on_sent (msg, success)
	if not success then
		self.app_messages:set_text (self.app_messages:get_text ().."\n\nFailed to send "..msg.context)
		local x, y = self.app_messages:get_scroll_size ()
		self.app_messages:set_scroll_org (0, y)
	end
end



function appFrame:on_event (event, p1, p2, p3, p4, p5)
	if event == "btn_click" then
		if p1:get_id () == ID_MENUBTN then
			self:on_menu ()
			return true
		end

		if p1:get_id () == ID_BALANCE then
			return self:on_command (IDM_BALANCE)
		end

		if p1:get_id () == ID_CHANGEPIN then
			return self:on_command (IDM_CHANGEPIN)
		end

		if p1:get_id () == ID_TRANSFER then
			return self:on_command (IDM_TRANSFER)
		end

	elseif event == "menu_cmd" then
		return self:on_command (p1)
	end

	return false
end



function appFrame:on_idle (idle_count)
	return false
end



function appFrame:on_alarm (alarm_id)
	return false
end



function appFrame:on_timer (timer_id)
	return false
end



function appFrame:on_move ()
	self.app_messages:move (1, 2, self.width - 2, self.height - 3)

	return false
end



function appFrame:on_destroy_wnd ()
end



function appFrame:on_child_key (wnd, key, ctrl, alt, shift)
	if win.applicationFrame.on_child_key (self, wnd, key, ctrl, alt, shift) then
		return true
	end

	if ctrl and not alt and not shift then
		if key == keys.KEY_L then
			return self:on_command (IDM_BALANCE)
		end

		if key == keys.KEY_P then
			return self:on_command (IDM_CHANGEPIN)
		end

		if key == keys.KEY_T then
			return self:on_command (IDM_TRANSFER)
		end

		if key == keys.KEY_M then
			return self:on_command (IDM_CLRMSGS)
		end
	end

	return false
end



function appFrame:on_frame_activate (active)
end



function appFrame:on_quit ()
	if self.connection_name then
		self:comm_close (self.connection_name)
	end

	return false
end



function appFrame:on_menu ()
	local menu = win.menuWindow:new (self)

	menu:add_string ("Balance    Ctrl+L", IDM_BALANCE)
	menu:add_string ("Change Pin Ctrl+P", IDM_CHANGEPIN)
	menu:add_string ("Transfer   Ctrl+T", IDM_TRANSFER)
	menu:add_string ("-----------------")
	menu:add_string ("Clear Msgs Ctrl+M", IDM_CLRMSGS)
	menu:add_string ("-----------------")
	menu:add_string ("Quit App",          IDM_QUITAPP)

	menu:track (0, 1)
end



function appFrame:on_command (cmd_id)
	if cmd_id == IDM_BALANCE then
		self:on_balance ()
		return true
	end

	if cmd_id == IDM_CHANGEPIN then
		self:on_change_pin ()
		return true
	end

	if cmd_id == IDM_TRANSFER then
		self:on_transfer ()
		return true
	end

	if cmd_id == IDM_CLRMSGS then
		self.app_messages:set_text ()
		return true
	end

	if cmd_id == IDM_QUITAPP then
		self:quit_app ()
		return true
	end

	return false
end



function appFrame:on_create ()
	local instance = self:get_desktop ():get_wnd_by_id (ID_BANKING_FRAME, false)
	if instance then
		instance:set_active_top_frame ()

		return false
	end

	self:set_id (ID_BANKING_FRAME)
	self:dress (APP_TITLE)

	local menuBtn = win.buttonWindow:new (self, ID_MENUBTN, 0, 0, "Menu")
	menuBtn:set_colors (menuBtn:get_colors ().frame_text,
							  menuBtn:get_colors ().title_back,
							  menuBtn:get_colors ().frame_back)
	menuBtn:move (nil, nil, nil, nil, win.WND_TOP)

	win.buttonWindow:new (self, ID_BALANCE, 1, 1, "Bal")
	win.buttonWindow:new (self, ID_CHANGEPIN, 5, 1, "Pin")
	win.buttonWindow:new (self, ID_TRANSFER, 9, 1, "Trans")
	self.app_messages = win.textWindow:new (self, ID_MESSAGES, 1, 2,
														 self.width - 2, self.height - 3)
	self.app_messages:set_color (self:get_colors ().wnd_text)
	self.app_messages:set_bg_color (self:get_colors ().wnd_back)

	local ini = fs.load_ini (self:get_app_path ()..".ini")
	if ini then
		self.account = ini:find ("account")
		self.retail = ini:find ("retail")
		self.bankname = ini:find ("bankname")
		self.banknetwork = ini:find ("banknetwork")
	end
	self.banknetwork = tostring (self.banknetwork or "mine_bank_network")
	self.bankname = tostring (self.bankname or "mineBank")

	self:set_active_top_frame ()

	local con = self:comm_open (nil, 5)
	if not con then
		self:msgbox ("Connection", "Could not connect to modem!", term.colors.red)
		return false
	end

	self.connection_name = con:get_name ()
	self.app_id = APP_TITLE..tostring (math.random (1, 65535))
	self:want_messages (self.app_id, self.connection_name)
	self:want_messages (self.banknetwork, self.connection_name)

	return true
end



function appFrame:on_balance ()
	local dlg = balanceDlg:new (self)

	if dlg:do_modal (self.account) == ID_OK then
		self:send_message (self.bankname, self.banknetwork, "mine_bank_balance",
								 {
									 application = self.app_id,
									 account = dlg.bal_acc:get_text (),
									 pin = dlg.bal_pin:get_text ()
								 },
								  self.connection_name)
	end
end



function appFrame:on_change_pin ()
	local dlg = changePinDlg:new (self)

	if dlg:do_modal (self.account) == ID_OK then
		self:send_message (self.bankname, self.banknetwork, "mine_bank_change_pin",
								 {
									 application = self.app_id,
									 account = dlg.pin_acc:get_text (),
									 pin = dlg.pin_old:get_text (),
									 new_pin = dlg.pin_new:get_text ()
								 },
								 self.connection_name)
	end
end



function appFrame:on_transfer ()
	local dlg = transferDlg:new (self)

	if dlg:do_modal (nil, self.retail) == ID_OK then
		self:send_message (self.bankname, self.banknetwork, "mine_bank_transfer",
								 {
									 application = self.app_id,
									 account = dlg.trans_from:get_text (),
									 pin = dlg.trans_pin:get_text (),
									 to = dlg.trans_to:get_text (),
									 amount = dlg.trans_amount:get_text ()
								 },
								 self.connection_name)
	end
end



appFrame:run_app ()
