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

local APP_TITLE      = "email"

local ID_MENUBTN     = 101
local ID_TO          = 102
local ID_SUBJECT     = 103
local ID_MESSAGE     = 104

local IDM_SEND       = 1001
local IDM_QUITAPP    = 1002

local ID_EMAIL_FRAME    = 32154


function appFrame:on_sent (msg, success)
	if msg.context == "email_send" then
		self:comm_close (self.app_conn_name)
		self.app_conn_name = nil

		if success then
			local path;

			repeat
				path = self.app_data_path.."/sent/s"..
						 tostring (math.random (1, 65535))..".email"
			until not fs.file_exists (path)

			local file = io.open (path, "w")
			if file then
				file:write (utils.serialize (msg.data.email))
				file:close ()
			else
				self:msgbox ("Sent", "Email was sent but could not save a copy.", term.colors.red)
			end

			local instance = self:get_desktop ():get_wnd_by_id (ID_EMAIL_FRAME)
			if instance then
				instance:send_event ("reload_list", "sent")
			end

			self.app_msg_sent = true
			self:quit_app ()
		else
			self:msgbox ("Error", "Could not send email!", term.colors.red)
		end
	end

	return true
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

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

	elseif event == "input_change" then
		if p1:get_id () == ID_SUBJECT then
			self:set_title ((p1:get_text ():len() > 0 and p1:get_text ()..":") or ""..APP_TITLE)
			return true
		end
	end

	return false
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_S then
			return self:on_command (IDM_SEND)
		end
	end

	return false
end


function appFrame:on_quit ()
	if self.app_conn_name then
		self:msgbox ("Sending", "Send in progress.", term.colors.orange)
		return true
	end

	if not self.app_msg_sent then
		if not cmndlg.confirm (self, "Unsent", "Message not sent. Quit anyway?") then
			return true
		end
	end

	return false
end


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

	menu:add_string ("Send Ctrl+S", IDM_SEND)
	menu:add_string ("-----------")
	menu:add_string ("Quit App",    IDM_QUITAPP)

	menu:track (0, 1)
end


function appFrame:on_command (cmdId)
	if cmdId == IDM_SEND then
		self:on_send ()
		return true
	end

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

	return false
end


function appFrame:on_move ()
	self.app_to:move (1, 1, self.width - 2)
	self.app_subject:move (1, 3, self.width - 2)
	self.app_message:move (1, 5, self.width - 2, self.height - 6)

	return false
end


function appFrame:on_create ()
	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)

	self.app_to = win.inputWindow:new (self, ID_TO, 1, 1, self.width - 2,
												  nil, "Recipient")
	self.app_subject = win.inputWindow:new (self, ID_SUBJECT, 1, 3,
														 self.width - 2, nil, "Subject")
	self.app_message = win.editWindow:new (self, ID_MESSAGE, 1, 5, self.width - 2,
														self.height - 6, nil, "Message")

	self.app_app_folder = self:get_app_path ():sub (1, -(fs.path_name (self:get_app_path ()):len () + 1))
	self.app_data_path = self.app_app_folder.."data/email"
	self.app_conn_name = nil
	self.app_msg_sent = false

	if #app_args > 0 then
		self.app_to:set_text (app_args[1])
		self.app_subject:set_focus ()
	else
		self.app_to:set_focus ()
	end

	self:set_active_top_frame ()

	return true
end


function appFrame:on_send ()
	local recipient = self.app_to:get_text ()
	if recipient:len () > 2 and recipient:find ("@", 1) then
		local ini = fs.load_ini (self.app_app_folder.."email.ini")

		if ini then
			local address = tostring (ini:find ("address") or "")
			local network = tostring (ini:find("network") or "wide_area_network")
			local timeout = tonumber(ini:find("timeout")) or 5

			if address:len () > 2 and address:find ("@", 1) then
				local con = self:comm_open (nil, timeout)
				if not con then
					self:msgbox ("Connection", "Could not connect to modem!", term.colors.red)
					return
				end

				self.app_conn_name = con:get_name ()
				self:want_messages (network, self.app_conn_name)

				local domain = recipient:sub (recipient:find ("@", 1) + 1)
				local account = recipient:sub (1, recipient:find ("@", 1) - 1)

				self:send_message (domain, network, "email_send",
										 {
											 account = account,
											 email =
											 {
												 recipient = recipient,
												 sender = address,
												 time = os.time (),
												 subject = self.app_subject:get_text (),
												 message = self.app_message:get_text ()
											 }
										 }, self.app_conn_name)
			else
				self:msgbox ("Account", "Invalid account settings!", term.colors.red)
			end
		else
			self:msgbox ("Account", "No account set up!", colors.red)
		end
	else
		self.app_to:set_error (true)
		self.app_to:set_focus ()
	end
end


appFrame:run_app ()
