/*
 * Copyright © 2012 Keith Packard <keithp@keithp.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 */

autoload Client;
autoload Nichrome;
autoload Nichrome::Box;
autoload Nichrome::Text;
autoload Nichrome::Textline;
autoload Nichrome::Label;
autoload Nichrome::Scrollbar;
autoload Nichrome::Solid;

extend namespace Client {
	public namespace Messages {
		import Nichrome;

		public typedef messages_t;

		protected typedef void (*messages_t m, string text) callback_t;

		public typedef struct {
			*nichrome_t		ui;
			*Box::box_t		hbox;
			*Box::box_t		vbox;
			*Text::text_t		output;
			*Scrollbar::scrollbar_t	scrollbar;
			*Label::label_t		name;
			*Textline::textline_t	input;
			callback_t		done_callback;
		} messages_t;

		protected void add (&messages_t m, string user, string message) {
			Text::insert(m.output, String::length(m.output->text),
				     sprintf ("<%s> %s\n", user, message));
			while (Text::scroll_down(m.output))
				;
		}

		void send(&messages_t m) {
			string s = m.input->text;
			Textline::set_text(m.input, "");
			m.done_callback(&m, s);
		}

		protected void set_focus(*messages_t m) {
			Nichrome::set_key_focus(m->ui, m->input);
		}

		protected *messages_t new(&nichrome_t ui, int lines, callback_t done_callback, string name) {
			*messages_t m = &(messages_t) {
				.ui = &ui,
				.output = Text::new(&ui),
				.name = Label::new(&ui, sprintf("%s: ", name)),
				.input = Textline::new(&ui, 40),
				.done_callback = done_callback
			};
			bool key_callback(&Textline::textline_t widget, string key) {
				switch (key) {
				case "Return": send(m); break;
				default: return false;
				}
				return true;
			}
			m->input->callback = key_callback;
			m->scrollbar = Text::scrollbar(m->output);
			m->hbox = Box::new(Box::dir_t.horizontal,
					   Box::widget_item(m->output, 1, 1),
					   Box::widget_item(m->scrollbar, 0, 1));
			m->vbox = Box::new(Box::dir_t.vertical,
					   Box::box_item(m->hbox),
					   Box::widget_item(Solid::new(&ui, 1, 1), 1, 0),
					   Box::box_item(Box::new(Box::dir_t.horizontal,
								  Box::widget_item(m->name, 0),
								  Box::widget_item(m->input, 1, 0))));
			return m;
		}
	}
}
