# FILE: ui-main.pl
# DESCRIPTION: Discus User Interface
#-------------------------------------------------------------------------------
# DISCUS COPYRIGHT NOTICE
#
# Discus is copyright (c) 2002 by DiscusWare, LLC, all rights reserved.
# The use of Discus is governed by the Discus License Agreement which is
# available from the Discus WWW site at:
#    http://www.discusware.com/discus/license
#
# Pursuant to the Discus License Agreement, this copyright notice may not be
# removed or altered in any way.
#-------------------------------------------------------------------------------

use strict;
use vars qw($GLOBAL_OPTIONS $DCONF $PARAMS);

###
### user_interface_main_control
###
### Main Discus User Interface
###

sub user_interface_main_control {
	my ($FORMref, $cookie_str, $error, $extra) = @_;
	$FORMref = parse_form($ENV{'QUERY_STRING'}, $ENV{'CONTENT_LENGTH'}) if ! defined $FORMref;
	my $subst = {};
	$subst->{general}->{authentication_error} = 1 if ($FORMref->{username} ne "" || $FORMref->{password} ne "");
	dreq("template");
	ui_show_topics(undef, $FORMref) if $FORMref->{pg} eq "topics";
	$subst->{extra} = $extra;
	$FORMref->{pg} = "uilogin" if $error;
	$FORMref->{pg} = "" if $FORMref->{pg} eq "flogin" && ! $DCONF->{pro};
	my $flag = ( $error ? 1 : 0 );
	if ($FORMref->{pg} eq "emergency") {
		dreq("emergpw");
		make_emergency_password($FORMref);
	}
	if ($FORMref->{pg} eq "logout") {
		dreq("ui-prfle");
		$cookie_str .= uiprfle_logout($FORMref, 2);
		screen_out("usrlgout", {}, $cookie_str);
	}
	if ($FORMref->{pg} eq "flogout") {
		dreq("ui-prfle");
		$cookie_str .= uiprfle_logout($FORMref, 2);
		$subst->{general}->{screen} = "uilogin";
		$subst->{general}->{forcedest} = "topics";
		$GLOBAL_OPTIONS->{secure_topics_file} = 2 if $GLOBAL_OPTIONS->{secure_topics_file} == 0;
		screen_out("usrlogin", $subst, $cookie_str);
	}
	if ($FORMref->{pg} eq "uilogin") {
		$FORMref->{pg} = "";
	}
	$FORMref->{pg} = $FORMref->{forcedest} if $FORMref->{forcedest};
	if (ref $extra eq 'HASH') {
		$subst->{general}->{screen} = "uilogin";
		$subst->{general}->{forcedest} = $extra->{forcedest};
		screen_out("usrlogin", $subst, undef);
	} elsif ($FORMref->{script} ne "" && $FORMref->{script} ne "discus") {
		my $script = $FORMref->{script}; $FORMref->{script} = "";
		my $fr = parse_form(unescape($FORMref->{query_string}), 0, undef);
		$FORMref = hash_merge($FORMref, $fr, 1);
		discus($script, $FORMref, undef);
	} elsif ($FORMref->{pg} eq "flogin") {
		$subst->{general}->{screen} = "uilogin";
		$subst->{general}->{forcedest} = "topics";
		$GLOBAL_OPTIONS->{secure_topics_file} = 2 if $GLOBAL_OPTIONS->{secure_topics_file} == 0;
		screen_out("usrlogin", $subst, undef);
	} elsif ($FORMref->{pg} eq "" && $FORMref->{sameframe} == 0 && $GLOBAL_OPTIONS->{use_no_frames} == 0) {
		$subst->{general}->{screen} = "framesetter";
		if ($ENV{QUERY_STRING} =~ m|^(\d+)/(\d+)|) {
			my $l = $ENV{QUERY_STRING};
			if ($l =~ m|^(\d+)/(\d+)#POST(\d+)|) {
				if ($DCONF->{pro}) {
					$subst->{general}->{right_frame_url} = "$DCONF->{authorize_reader}?file=/$1/$2.$DCONF->{ext}#POST$3";
				} else {
					$subst->{general}->{right_frame_url} = "$DCONF->{message_url}/$1/$2.$DCONF->{ext}#POST$3";
				}
			} elsif ($l =~ m|^(\d+)/(\d+)|) {
				if ($DCONF->{pro}) {
					$subst->{general}->{right_frame_url} = "$DCONF->{authorize_reader}?file=/$1/$2.$DCONF->{ext}";
				} else {
					$subst->{general}->{right_frame_url} = "$DCONF->{message_url}/$1/$2.$DCONF->{ext}";
				}
			}
		} elsif ($FORMref->{post} != 0) {
			my $post = $FORMref->{post};
			my ($topic, $page) = ui_get_post_location($FORMref->{tpc}, $post);
			if ($page == 0) {
				my $l = read_language()->{POST_WAS_NOT_FOUND_EXPLANATION};
				$l =~ s/\%showurl/$DCONF->{script_url}\/show.$DCONF->{cgi_extension}?$topic\/$topic/g;
				error_message(read_language()->{POST_WAS_NOT_FOUND}, $l, 0, 1);
			} elsif ($DCONF->{pro}) {
				$subst->{general}->{right_frame_url} = "$DCONF->{authorize_reader}?file=/$topic/$page.$DCONF->{ext}#POST$post";
			} else {
				$subst->{general}->{right_frame_url} = "$DCONF->{message_url}/$topic/$page.$DCONF->{ext}#POST$post";
			}
		} else {
			$subst->{general}->{right_frame_url} = "$DCONF->{script_url}/discus.$DCONF->{cgi_extension}?pg=topics";
		}
	} elsif ($FORMref->{pg} eq "" && ($GLOBAL_OPTIONS->{use_no_frames} == 1 || $FORMref->{sameframe} == 1)) {
		if ($ENV{QUERY_STRING} =~ m|^(\d+)/(\d+)|) {
			my $l = $ENV{QUERY_STRING};
			if ($l =~ m|^(\d+)/(\d+)#POST(\d+)|) {
				if ($DCONF->{pro}) {
					dreq("authwrap-PRO");
					$FORMref->{file} = "/$1/$2.$DCONF->{ext}";
					auth_wrapper($FORMref);
				} else {
					seturl("$DCONF->{message_url}/$1/$2.$DCONF->{ext}#POST$3");
				}
			} elsif ($l =~ m|^(\d+)/(\d+)|) {
				if ($DCONF->{pro}) {
					dreq("authwrap-PRO");
					$FORMref->{file} = "/$1/$2.$DCONF->{ext}";
					$FORMref->{anchor} = undef;
					auth_wrapper($FORMref);
				} else {
					seturl("$DCONF->{message_url}/$1/$2.$DCONF->{ext}");
				}
			}
		} elsif ($FORMref->{post} != 0) {
			my $post = $FORMref->{post};
			my ($topic, $page) = ui_get_post_location($FORMref->{tpc}, $post);
			if ($page == 0) {
				my $l = read_language()->{POST_WAS_NOT_FOUND_EXPLANATION};
				$l =~ s/\%showurl/$DCONF->{script_url}\/show.$DCONF->{cgi_extension}?$topic\/$topic/g;
				error_message(read_language()->{POST_WAS_NOT_FOUND}, $l, 0, 1);
			} elsif ($DCONF->{pro}) {
				dreq("authwrap-PRO");
				$FORMref->{file} = "/$topic/$page.$DCONF->{ext}";
				$FORMref->{anchor} = undef;
				auth_wrapper($FORMref);
			} else {
				seturl("$DCONF->{message_url}/$topic/$page.$DCONF->{ext}#POST$post");
			}
		} elsif ($FORMref->{topic} != 0 && $DCONF->{pro}) {
			dreq("authwrap-PRO");
			my ($v, $cache, $ckstr, $result, $privcache) = ui_validate_login($FORMref, 0);
			auth_wrap_page($FORMref->{topic}, $FORMref->{page}, $ckstr);
		} else {
			$subst->{general}->{screen} = "topics";
			ui_show_topics(undef, $FORMref, $cookie_str, $flag, $extra);
		}
	} elsif (($FORMref->{pg} eq "next" || $FORMref->{pg} eq "prev") && $FORMref->{topic} =~ m|^\d+$|) {
		my ($page, $tree) = ui_get_next_prev_page($FORMref->{topic}, $FORMref->{page}, $FORMref->{pg});
		my $topic = $FORMref->{topic};
		if (-e "$DCONF->{message_dir}/$topic") {
			my $hashref = GetPage($topic, $page, { no_lock => 1, no_unlock => 1 });
			$hashref->{general}->{subtopic_raw} = 0;
			$hashref->{general}->{messages_raw} = 0;
			$hashref->{sublist} = expand_sublist($hashref->{sublist}, $topic, $tree);
			header($cookie_str);
			print SetPage($hashref, { return_val => 1 });
			program_exit(0);
		} elsif ($DCONF->{pro}) {
			dreq("authwrap-PRO");
			my $u = {};
			$u->{file} = "/$topic/$page.$DCONF->{ext}";
			$u->{COOKIE} = $FORMref->{COOKIE};
			auth_wrapper($u);
		}
	} else {
		$subst->{general}->{screen} = $FORMref->{pg};
		ui_show_topics(undef, $FORMref, $cookie_str, $flag) if $FORMref->{pg} eq "topics";
	}
	screen_out("uimain", $subst, $cookie_str);
}

###
### ui_get_post_location
###
### Locates a post by post number and topic number by looking in the tree file
###

sub ui_get_post_location {
	my ($topic, $post, $treecache) = @_;
	$treecache = read_tree($topic, { no_lock => 1, no_unlock => 1 }) if ! defined $treecache;
	foreach my $line (@{ $treecache }) {
		foreach my $postnum (split(/,/, $line->{post_list})) {
			return ($topic, $line->{page}, $line, $treecache) if $post == $postnum;
		}
	}
	return ($topic, 0, undef, $treecache);
}

###
### ui_show_topics
###
### Spits out a skinned version of the board-topics.html file
###

sub ui_show_topics {
	my ($in_topiclist, $FORMref, $cookie_str, $flag, $extra) = @_;
	if ($FORMref->{action} ne "login" && $GLOBAL_OPTIONS->{use_static_topic_document} == 1 && -e "$DCONF->{message_dir}/$DCONF->{board_topics_file}") {
		my $X = readfile("$DCONF->{message_dir}/$DCONF->{board_topics_file}", "ui_show_topics", { no_lock => 1, no_unlock => 1 });
		header($cookie_str);
		print @{$X};
		program_exit(0);
	}
	dreq("topic-pg");
	$in_topiclist = read_topic_page({ no_lock => 1, no_unlock => 1, zero_ok => 1 }) if ! defined $in_topiclist;
	if ($DCONF->{pro}) {
		dreq("authwrap-PRO");
		($in_topiclist, $cookie_str) = topic_list_manipulate($in_topiclist, $FORMref, $cookie_str, $flag, $extra);
	}
	$in_topiclist->{return_val} = 1;
	if ($FORMref->{action} eq "login" && $FORMref->{script} =~ m%\W(search|allusers|board-viewtree|board-newmessages)\.$DCONF->{cgi_extension}$%) {
		my $script = $1;
		my $FORM = parse_form(unescape($FORMref->{query_string}), 0);
		$FORM->{COOKIE} = $FORMref->{COOKIE};
		while ($cookie_str =~ m|Set-Cookie: (\w+)$DCONF->{COOKIE_ID}=(.*?);|g) {
			$FORM->{COOKIE}->{$1} = unescape($2);
		}
		discus($1, $FORM, $cookie_str);
	}
#	print "Content-type: text/plain\n\n";
	header($cookie_str);
	print write_topic_page($in_topiclist);
	program_exit(0);
}

###
### ui_get_next_prev_page
###
### Returns next or previous page number
###

sub ui_get_next_prev_page {
	my ($topic, $page, $action, $tree_cache) = @_;
	my $t = (defined $tree_cache ? $tree_cache : read_tree($topic, { no_lock => 1, no_unlock => 1 }));
	my $lc = 0;
	my @j = @{ $t };
	my $parent = $topic;
	while (my $x = _ui_grab_page(\@j, $action)) {
		$parent = $x->{parent} if $x->{page} == $page;
		next if $x->{islink};
		if ($x->{page} == $page) {
			$lc = $x->{level};
		} elsif ($lc == 0) {
			next;
		} elsif ($lc == $x->{level}) {
			return ($x->{page}, $t);
		} elsif ($lc > $x->{level}) {
			return ($parent, $t);
		}
	}
	return $parent;
}

sub _ui_grab_page {
	my ($array, $action) = @_;
	return pop @{ $array } if $action eq "prev";
	return shift @{ $array } if $action eq "next";
}

1;
