/*
 *  SPL - The SPL Programming Language
 *  Copyright (C) 2004, 2005  Clifford Wolf <clifford@clifford.at>
 *
 *  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; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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
 *
 *  friends.webspl: A nice example for a WebSPL application
 */

load "task";
load "cgi";

/*
 * Friends Data
 */

var friends;

object Friend {
	var id;
	static friends_id_counter = 1;

	var name = "Unnamed";
	var phone = "";
	var email = "";
	var addr = "";
	var links;

	var template = undef;
	var sid = undef;

	// interface for Win object
	var title = "unnamed";
	var winid = undef;

	method get_html() {
		var friends_list = "";
		var html;

		foreach f (links) {
			friends_list = friends_list ~
				'(<a href="${cgi.url}?sid=${sid}&delfriend=$f">X</a>)\n' ~
				'<a href="${cgi.url}?sid=${wmsid}&newwin=$f">${friends.[f].name}</a><br>\n';
		}

		if ( template ~== "show" )
			html = #file-as-template entry_show.spltpl;
		else
		if ( template ~== "edit" )
			html = #file-as-template entry_edit.spltpl;

		return html;
	}

	method winmain(_sid) {
		title = name;
		sid = _sid;
		while (1) {
			template = "show";
			bother_user();
			if ( declared cgi.param.edit ) {
				template = "edit";
				bother_user();
				name = cgi.param.new_name;
				phone = cgi.param.new_phone;
				email = cgi.param.new_email;
				addr = cgi.param.new_addr;
				title = name;
			}
			if ( declared cgi.param.delfriend ) {
				delete friends.[id].links.[cgi.param.delfriend];
				delete friends.[cgi.param.delfriend].links.[id];
			}
			if ( declared cgi.param.delete ) {
				delete friends.[id];
				foreach f (friends)
					delete friends.[f].links.[id];
				windows.[winid].finish();
			}
		}
	}

	method init(n) {
		if (defined n) name = n;
		id = "friend" ~ friends_id_counter++;
		friends.[id] = this;
		return id;
	}
}

// create some dummy data
{
	function linkFriends(a, b) {
		friends.[a].links.[b] = 1;
		friends.[b].links.[a] = 1;
	}

	var raffi    = new Friend("Raffi");
	var karin    = new Friend("Karin");
	var stefan   = new Friend("Stefan");
	var philipp  = new Friend("Philipp");
	var kim      = new Friend("Kim");
	var thomas   = new Friend("Thomas");
	var brigitte = new Friend("Brigitte");

	linkFriends(raffi, karin);
	linkFriends(raffi, kim);
	linkFriends(raffi, thomas);

	linkFriends(karin, kim);

	linkFriends(stefan, philipp);
	linkFriends(stefan, kim);
	linkFriends(philipp, kim);

	linkFriends(thomas, brigitte);
}


/*
 * Windowmanager
 */

var wmsid = cgi.sid;
var windows;

object Win {
	static windows_z_counter = 0;
	static windows_id_counter = 0;

	var id, sid;
	var content;

	var posx = 100;
	var posy = 100;
	var posz = 0;

	method get_html() {
		return #file-as-template window.spltpl;
	}

	method main() {
		content.winmain(cgi.sid);
	}

	method finish() {
		content.title = undef;
		content.winid = undef;
		delete windows.[id];
		write( #file-as-template main.spltpl );
		task_kill(id);
	}

	method init(content_ptr) {
		if ( defined content_ptr.winid ) {
			windows.[content_ptr.winid].posz = windows_z_counter++;
			return undef;
		}

		id = "win" ~ windows_id_counter++;
		windows.[id] = this;

		content = content_ptr;
		content.winid = id;

		posy = 50 + ((windows_id_counter-1) % 5)*20;
		posx = windows.[id].posy + 150;
		posz = windows_z_counter++;

		task_create(id, "main();", this);
		task_public(id);
		task_continue(id);
		return id;
	}
}

function menu_html() {
	var html = "<p>\n";
	foreach f (friends) {
		html = html ~ '<b><nobr><a href="${cgi.url}?sid=${wmsid}&newwin=$f">${friends.[f].name}</a></nobr></b><br>\n';
	}
	html = html ~ '</p><p>\n';
	html = html ~ '<b><nobr><a href="${cgi.url}?sid=${wmsid}&newfriend=1">Add New Entry</a></nobr></b><br>\n';
	html = html ~ '<b><nobr><a href="${cgi.url}?sid=${wmsid}&link=1">Link All Open</a></nobr></b><br>\n';
	html = html ~ '</p>\n';
	return html;
}

function windows_html() {
	var html = "";
	foreach w (windows) {
		html = html ~ windows.[w].get_html();
	}
	return html;
}

function bother_user() {
	write( #file-as-template main.spltpl );
	task_pause();
}

while (1) {
	if ( declared cgi.param.newfriend ) {
		new Win(friends.[new Friend()]);
		task_pause();
	} else
	if ( declared cgi.param.newwin )
		if ( defined new Win(friends.[cgi.param.newwin]) )
			task_pause();
		else
			bother_user();
	else
		bother_user();

	if ( declared cgi.param.win ) {
		var w = cgi.param.win;
		windows.[w].posz = Win.windows_z_counter++;
		if ( declared cgi.param.newx ) windows.[w].posx = cgi.param.newx;
		if ( declared cgi.param.newy ) windows.[w].posy = cgi.param.newy;
		if ( declared cgi.param.close ) windows.[w].finish();
	}

	if ( declared cgi.param.link ) {
		foreach a (friends) {
			if ( defined friends.[a].winid )
				foreach b (friends) {
					if ( defined friends.[b].winid && a ~!= b )
						friends.[a].links.[b] = 1;
				}
		}
	}
}

