## OpenCA::UI::HTML.pm 
##
## Copyright (C) 2000-2003 Michael Bell <michael.bell@web.de>
## All rights reserved.
##
##    This library is free software; you can redistribute it and/or
##    modify it under the terms of the GNU Lesser General Public
##    License as published by the Free Software Foundation; either
##    version 2.1 of the License, or (at your option) any later version.
##
##    This library 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
##    Lesser General Public License for more details.
##
##    You should have received a copy of the GNU Lesser General Public
##    License along with this library; if not, write to the Free Software
##    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
##

use strict;

package OpenCA::UI::HTML;

use CGI;
use Locale::Messages (':locale_h');
use Locale::Messages (':libintl_h');

use FileHandle;
our ($STDERR, $STDOUT);
$STDOUT = \*STDOUT;
$STDERR = \*STDERR;

our ($errno, $errval);

($OpenCA::UI::HTML::VERSION = '$Revision: 1.11 $' )=~ s/(?:^.*: (\d+))|(?:\s+\$$)/defined $1?"0\.9":""/eg;

##################################
##       initialization         ##
##################################

## Create an instance of the Class
sub new {
    my $that = shift;
    my $class = ref($that) || $that;

    my $self = {
                DEBUG         => 0,
                CONTENT_TYPE  => 0,
                debug_fd      => $STDOUT,
                ## debug_msg  => ()
               };

    bless $self, $class;

    my $keys = { @_ };

    ## this class expects the following parameters:
    ##     - HTDOCS_URL_PREFIX
    ##     - LANGUAGE
    ##
    ## we try to handle all types of malformed parameters

    foreach my $help (keys %{$keys})
    {
        if ($help =~ /LANG/i)
        {
            $self->{LANG} = $keys->{$help};
	} elsif ($help =~ /CHARSET/i) {
            $self->{CHARSET} = $keys->{$help};
        } elsif ($help =~ /(HTDOCS|URL|PREFIX)/i) {
            $self->{HTDOCS} = $keys->{$help};
        } elsif ($help =~ /CGI/i) {
            $self->{CGI} = $keys->{$help};
        } else {
            print STDERR i18nGettext ("OpenCA::UI::HTML->new: ignoring wrong parameter __NAME__",
                                      "__NAME__", $help);
        }
    }

    ## preparing CGI for object oriented handling
    $self->{CGI} = new CGI if (not exists $self->{CGI});

    return $self;
}

sub setLanguage
{
    my $self = shift;
    $self->{LANG}    = $_[0];
    $self->{CHARSET} = $_[1];
    return 1;
}

sub reset
{
    my $self = shift;
    $self->{CONTENT_TYPE} = 0;
    return 1;
}

##################################
##       debug handling         ##
##################################

sub sendDebug {

    my $self = shift;
    if ($_[0]) {
        $self->{debug_msg}[scalar @{$self->{debug_msg}}] = $_[0];
        $self->debug () if ($self->{DEBUG});
    } else {
        $self->sendContentType();
        my $msg;
        foreach $msg (@{$self->{debug_msg}}) {
            $msg =~ s/ /&nbsp;/g;
            my $oldfh = select $self->{debug_fd};
            print $msg."<br>\n";
            select $oldfh;
        }
        $self->{debug_msg} = ();
    }
}

##################################
##       error handling         ##
##################################

sub configError {
    my $self = shift;
    my @keys = @_;
    my $err = $keys[0];
    my $errno = ( $keys[1] or "600" );

    ## fix errorstring for HTML
    $err =~ s/\n(?!<br>)/<br>\n/g;

    $self->sendContentType ();
    print $STDOUT $self->{CGI}->start_html(-title=>gettext ("Configuration Error"),
                                   -lang     => $self->{LANG},
                                   -encoding => $self->{CHARSET},
                                   -BGCOLOR  => "#FFFFFF");
    print $STDOUT "<CENTER><BR><HR WIDTH=80%><BR></CENTER>";
    print $STDOUT "<OL><OL><H1><FONT COLOR=red>".gettext ("Error 690")."</FONT></H1>";
    print $STDOUT "<OL> <B>".gettext ("Configuration Error")."</B>. $err.</OL></OL></OL>";
    $self->closePage();
    die i18nGettext ("OpenCA: Error Trapped: __ERRVAL__",
                     "__ERRVAL__", $err);
}

sub generalError {
    my $self = shift;
    my @keys = @_;
    my $err = $keys[0];
    my $errNo = $keys[1];

    $errNo = 700 if ( not $errNo);

    ## fix errorstring for HTML
    $err =~ s/\n(?!<br>)/<br>\n/g;

    $self->sendContentType ();
    print $STDOUT $self->{CGI}->start_html(-title=>gettext ("General Error"),
                                   -lang     => $self->{LANG},
                                   -encoding => $self->{CHARSET},
                                   -BGCOLOR=>"#FFFFFF");
    print $STDOUT "<CENTER><BR><HR WIDTH=80%><BR></CENTER>";
    print $STDOUT "<OL><OL><H1><FONT COLOR=red>".
                      i18nGettext ("Error __ERRNO__", "__ERRNO__", $errNo).
                  "</FONT></H1>";
    print $STDOUT "<OL> <B>".gettext ("General Error")."</B>. $err.</OL></OL></OL>";

    closePage();

    die i18nGettext ("OpenCA: General error trapped __ERRNO__: __ERRVAL__",
                     "__ERRNO__", $errNo,
                     "__ERRVAL__", $err);
}

##################################
##       normal output          ##
##################################

sub sendContentType
{
    my $self = shift;

    if (not $self->{CONTENT_TYPE})
    {
        my $ct = "text/html";
        $ct = $_[0] if ($_[0]);
        print $STDOUT "Content-Type: $ct\n\n";
        $self->{CONTENT_TYPE} = $ct;
    }

    return $self->{CONTENT_TYPE};
}

sub libSendReply {
    my $self = shift;
    my $keys = { @_ };
#    my $ie_enroll="";
#    my @scripts = ();

    #if ($keys->{SIGN_FORM}) {
#        @scripts=({'language'=>'Javascript',
#                  'src'=>getRequired('HtdocsUrlPrefix').
#                      "/scripts/$self->{LANG}/signForm.js"},
#		  {'language'=>'VBScript',
#                   'src'=>getRequired ('HtdocsUrlPrefix') .
#                      "/scripts/$self->{LANG}/signForm.vbs"});
    #}

#    my @init_page = ();
#    push( @init_page, -title=>$keys->{NAME} )
#		if( $keys->{NAME} );

#    push( @init_page, -script=>{'language'=>'Javascript',
#                                'src'=>getRequired('HtdocsUrlPrefix').
#                                "/scripts/$self->{LANG}/signForm.js"},
#    		      -script=>{'language'=>'VBScript',
#                                'src'=>getRequired ('HtdocsUrlPrefix') .
#                                "/scripts/$self->{LANG}/signForm.vbs"});
#
#    push( @init_page, -meta=>{'info'=>"CAZZO: $#init_page"} );
#    my $page = $query->start_html( @init_page, -script=>$scripts[0],
#			-script=>$scripts[1] ) .
#    my $page = $query->start_html( @init_page ) .
#    my $page = $query->start_html( -title=>$keys->{NAME},
#			-meta=>{'created'=>"misc-utils.lib:libSendReply"},
#			-style=>{'src'=>getRequired ('HtdocsUrlPrefix') .
#					"default.css"},
#			-script=>$scripts[0],
#			-script=>$scripts[1]
#			) .
my $page =
'<!doctype html public "-//w3c//dtd html 4.0 transitional//en">'."\n".
'<html>'."\n".
'  <head>'."\n".
'    <meta http-equiv="Content-Type" content="text/html; charset='.$self->{CHARSET}.'">'."\n";
    $page .= '<title>'.$keys->{NAME}.'</title>' if (exists $keys->{NAME});
    $page .= "\n".
'    <link rel="stylesheet" href="'.$self->{HTDOCS}.'/default.css" type="text/css" />'."\n";
    $page .= "\n".
'    <script LANGUAGE="Javascript" SRC="'.$self->{HTDOCS}.'/scripts/'.$self->{LANG}.'/signForm.js">'."\n".
'    </script>'."\n".
'    <script LANGUAGE="VBScript" SRC="'.$self->{HTDOCS}.'/scripts/'.$self->{LANG}.'/signForm.vbs">'."\n".
'    </script>'."\n"
      if ($keys->{SIGN_FORM});
    $page .=
'    <!-- Use the Microsoft ActiveX control to install the certificate -->'."\n".
'    <object'."\n".
'        classid="clsid:43f8f289-7a20-11d0-8f06-00c04fc295e1"'."\n".
'        codebase=xenroll.dll'."\n".
'        id=certHelperOld>'."\n".
'    </object>'."\n".
'    <object'."\n".
'        classid= "clsid:127698e4-e730-4e5c-a2b1-21490a70c8a1"'."\n".
'        codebase=xenroll.dll'."\n".
'        id=certHelperNew>'."\n".
'    </object>'."\n";
    $page .=
'    <script LANGUAGE="Javascript" SRC="'.$self->{HTDOCS}.'/scripts/'.$self->{LANG}.'/ieEnroll.js">'."\n".
'    </script>'."\n"
      if ($keys->{IE_ENROLL_CERT});
    $page .=
'    <script LANGUAGE="VBScript" SRC="'.$self->{HTDOCS}.'/scripts/'.$self->{LANG}.'/ieCSR.vbs">'."\n".
'    </script>'."\n"
      if ($keys->{IE_REQUEST_CERT});
    $page .=
'  </head>'."\n";
  if ($keys->{IE_ENROLL_CERT})
  {
    $page .= '  <body class="back" onLoad="InstallCertIE(document.OPENCA);">';
  } elsif ($keys->{IE_REQUEST_CERT}) {
    $page .= '  <body class="back" onload="enumCSP()">';
  } else {
    $page .= '  <body>';
  }
  $page .=
'    &nbsp;'."\n";
  if ( $keys->{TARGET} ) {
  $page .=
	$self->{CGI}->start_multipart_form( -method=>"POST",
                                            -name  =>"OPENCA",
                                            -target=>$keys->{TARGET},
                                            -action=>$self->{CGI}->param("HTTP_CGI_SCRIPT" ));
  } else {
  $page .=
	$self->{CGI}->start_multipart_form( -method=>"POST",
                                            -name  =>"OPENCA",
                                            -action=>$self->{CGI}->param("HTTP_CGI_SCRIPT" ));
  }
  $page .=
'    <center>'."\n".
'    <table class="global">'."\n".
'      <tr>'."\n".
'        <td>'."\n".
'          <div class="page_headline">'."\n";
    $page .= $keys->{NAME} if (exists $keys->{NAME});
    $page .=
'          </div>'."\n".
'        </td>'."\n".
'      </tr>'."\n";
    $page .= "      <tr>\n"
        if (exists $keys->{EXPLANATION} or exists $keys->{SIGINFO});
    if (exists $keys->{EXPLANATION})
    {
        my $exp = $keys->{EXPLANATION};
        $exp =~ s/\n/<br>\n/;
        $page .= 
'        <td class="explanation">'."\n".
$exp."\n".
'        </td>'."\n";
    }
    if (exists $keys->{SIGINFO})
    {
        my $exp = $keys->{SIGINFO};
        $exp =~ s/\n/<br>\n/;
        $page .=
'        <td class="siginfo">'."\n".
$exp."\n".
'        </td>'."\n";
    }
    $page .= "      </tr>\n"
        if (exists $keys->{EXPLANATION} or exists $keys->{SIGINFO});
    if ($keys->{TIMESTAMP})
    {
        $page .=
'      <tr class="timestamp">'."\n".
'        <td class="timestamp">'."\n".
localtime()."\n".
'        </td>'."\n".
'      </tr>'."\n";
    }
    if (exists $keys->{ITEM_LIST})
    {
        my $list = $keys->{ITEM_LIST};
        $page .=
'      <tr>'."\n".
'        <td class="global_item_list">'."\n".
'         <center>'."\n".
'          <table class="item_list">'."\n".
'            <tr class="item_list">'."\n";
        foreach my $item (@{$list->{HEAD}})
        {
            $page .= '<th class="item_list">'.$item."</th>\n";
        }
        $page .=
'            </tr>'."\n";
        foreach my $item (@{$list->{BODY}})
        {
            $page .=
'            <tr class="item_list">'."\n";
            foreach my $b_item (@{$item})
            {
                $page .= '<td class="item_list">'.$b_item."</td>\n";
            }
            $page .=
'            </tr>'."\n";
        }
        $page .=
'          </table>'."\n".
'         </center>'."\n".
'        </td>'."\n".
'      </tr>'."\n";
    }
    if (exists $keys->{INFO_LIST})
    {
        my $list = $keys->{INFO_LIST};
        $page .=
'      <tr>'."\n".
'        <td class="global_info_list">'."\n".
'         <center>'."\n".
'          <table class="info_list">'."\n";
        if (exists $list->{HEAD})
        {
            $page .=
'            <tr class="info_list">'."\n";
            foreach my $item (@{$list->{HEAD}})
            {
                $page .= '<th class="info_list">'.$item."</th>\n";
            }
            $page .=
'            </tr>'."\n";
        }
        foreach my $item (@{$list->{BODY}})
        {
            $page .=
'            <tr class="info_list">'."\n";
            if (scalar @{$item} == 1)
            {
                $page .= '<th colspan="2" class="info_list">'.$item->[0]."</th>\n";
            } else {
                foreach my $b_item (@{$item})
                {
                    $page .= '<td class="info_list">'.$b_item."</td>\n";
                }
            }
            $page .=
'            </tr>'."\n";
        }
        $page .=
'          </table>'."\n".
'         </center>'."\n".
'        </td>'."\n".
'      </tr>'."\n";
    }
    if (exists $keys->{CMD_LIST})
    {
        my $list = $keys->{CMD_LIST};
        $page .=
'      <tr>'."\n".
'        <td class="global_cmd_list">'."\n".
'         <center>'."\n".
'          <table class="cmd_list">'."\n";
        if ($list->{HEAD})
        {
            $page .=
'            <tr class="cmd_list">'."\n";
            if (scalar @{$list->{HEAD}} == 1)
            {
                $page .= '<th class="cmd_list" colspan="2">'.$list->{HEAD}->[0]."</th>\n";
            } else {
                foreach my $item (@{$list->{HEAD}})
                {
                    $page .= '<th class="cmd_list">'.$item."</th>\n";
                }
            }
            $page .=
'            </tr>'."\n";
        }
        foreach my $item (@{$list->{BODY}})
        {
            $page .=
'            <tr class="cmd_list">'."\n";
            foreach my $b_item (@{$item})
            {
                $page .= '<td class="cmd_list">'.$b_item."</td>\n";
            }
            $page .=
'            </tr>'."\n";
        }
        $page .=
'          </table>'."\n".
'        </td>'."\n".
'      </tr>'."\n";
    }
    if (exists $keys->{CMD_PANEL})
    {
        my $list = $keys->{CMD_PANEL};
        $page .=
'      <tr>'."\n".
'        <td class="global_cmd_panel">'."\n".
'         <center>'."\n".
'          <table class="cmd_panel">'."\n".
'            <tr class="cmd_panel">'."\n";
        foreach my $item (@{$list})
        {
            $page .= '<td class="cmd_panel">'.$item."</td>\n";
        }
        $page .=
'            </tr>'."\n".
'          </table>'."\n".
'         </center>'."\n".
'        </td>'."\n".
'      </tr>'."\n";
    }
    $page .=
'    </table>'."\n";
    if (exists $keys->{HIDDEN_LIST})
    {
        my $list = $keys->{HIDDEN_LIST};
        foreach my $item (keys %{$list})
        {
            $page .= '<input type="hidden" name="'.$item.'" value="'.$list->{$item}."\">\n";
        }
    }
    $page .=
'    </center>'."\n".
'    </form>'."\n".
'  </body>'."\n".
'</html>'."\n";
    $self->sendContentType();
    print $STDOUT $page;
    return 1;
}

sub libSendMenu {

    my $self = shift;

    my $page =
'<html>'."\n".
'  <head>'."\n".
'    <meta http-equiv="Content-Type" content="text/html; charset='.$self->{CHARSET}.'">'."\n".
'    <title>OpenCA Menu</title>'."\n".
'    <link rel="stylesheet" href="'.$self->{HTDOCS}.'/default.css" type="text/css" />'."\n".
'  </head>'."\n".
'  <body>'."\n".
'    <!-- New Menu -->'."\n".
'    <div class="menu">'."\n".
'    <table cellpadding="0" cellspacing="0" border="0" width="100%">'."\n".
'      <tr>'."\n".
'        <td>'."\n".
'          '.$_[1].''."\n".
'        </td><td width="100%">'."\n".
'          <table cellpadding="0" cellspacing="0" border="0" width="100%">'."\n".
'            <tr>'."\n".
'              <td width="10">'."\n".
'              </td>'."\n".
'                '.$_[0].''."\n".
'            </tr>'."\n".
'          </table>'."\n".
'        </td><td>'."\n".
'          '.$_[2].''."\n".
'        </td>'."\n".
'      </tr>'."\n".
'    </table>'."\n".
'    </div>'."\n".
'  </body>'."\n".
'</html>';

    print $STDOUT $page;
    return 1;
}

sub libSendStatic
{
    my $self = shift;
    my $keys = { @_ };

    my $page =
'<!doctype html public "-//w3c//dtd html 4.0 transitional//en">'."\n".
'<html>'."\n".
'  <head>'."\n".
'    <meta http-equiv="Content-Type" content="text/html; charset='.$self->{CHARSET}.'">'."\n";
    $page .= '<title>'.$keys->{NAME}.'</title>' if (exists $keys->{NAME});
    $page .=
'    <link rel="stylesheet" href="'.$self->{HTDOCS}.'/default.css" type="text/css" />'."\n";
  $page .= '  <body>';
  $page .=
'    &nbsp;'."\n".
'    <form method="post">'."\n".
'    <center>'."\n".
'    <table class="global">'."\n".
'      <tr>'."\n".
'        <td>'."\n".
'          <div class="page_headline">'."\n";
    $page .= $keys->{NAME} if (exists $keys->{NAME});
    $page .=
'          </div>'."\n".
'        </td>'."\n".
'      </tr>'."\n";
    if (exists $keys->{EXPLANATION})
    {
        my $exp = $keys->{EXPLANATION};
        $exp =~ s/\n/<br>\n/;
        $page .=
'      <tr>'."\n".
'        <td class="explanation">'."\n".
$exp.
'        </td>'."\n".
'      </tr>'."\n";
    }
    if ($keys->{TIMESTAMP})
    {
        $page .=
'      <tr class="timestamp">'."\n".
'        <td class="timestamp">'."\n".
localtime().''."\n".
'        </td>'."\n".
'      </tr>'."\n";
    }
    if (exists $keys->{ITEM_LIST})
    {
        my $list = $keys->{ITEM_LIST};
        $page .=
'      <tr>'."\n".
'        <td class="global_item_list">'."\n".
'         <center>'."\n".
'          <table class="item_list">'."\n";
        foreach my $item (@{$list})
        {
            my $b_item = shift @{$item};
            $page .=
'            <tr class="item_list">'."\n".
'              <th class="item_list">'."\n".
'                '.$b_item.''."\n".
'              </th>'."\n".
'            </tr>'."\n";
            foreach my $b_item (@{$item})
            {
                $page .= '<tr><td class="item_list">'.$b_item."</td></tr>\n";
            }
        }
        $page .=
'          </table>'."\n".
'         </center>'."\n".
'        </td>'."\n".
'      </tr>'."\n";
    }
    $page .=
'    </table>'."\n".
'    </center>'."\n".
'    </form>'."\n".
'  </body>'."\n".
'</html>'."\n";
    print $STDOUT $page;
    return 1;
}

##################################
##      logging output          ##
##################################

sub startLogPage {

    my $self  = shift;
    my $title = shift;
    my $ret;

    $title = gettext ("Proceeding") if ( not $title );

    $ret = $self->{CGI}->start_html(-title=>$title,
                              -lang     => $self->{LANG},
                              -encoding => $self->{CHARSET},
                              -BGCOLOR  => "#FFFFFF",
                              -TEXT     => "#445599" );

    $ret .=  "<CENTER>";
    $ret .=  "<FONT SIZE=\"+3\">";
    $ret .=  "<B>$title</B></FONT><BR>\n";
    $ret .=  "<FONT SIZE=\"+1\">";
    $ret .=  "(".gettext ("Please wait until operation completes").")</FONT><BR>\n";
    $ret .=  "<HR WIDTH=80%>";
    $ret .=  "</CENTER>\n";
    $ret .=  "<div class=\"log\">\n";

    return $ret;
}


sub closeLogPage {

    my $self = shift;
    my $ret;

    $ret = "</div>\n";
    $ret = "<CENTER><HR WIDTH=\"80%\"></CENTER>";
    ## $ret .= getCopyRight();

    $ret .= $self->{CGI}->end_html();

    return $ret;
}

sub addLogSection {
    my $self = shift;
    my $line = shift;
    my $ret;

    $ret = "<FONT SIZE=+1><FONT FACE=\"Arial, Helvetica\">\n";
    $ret .= $line;

    return $ret;
}

sub closeLogSection {
    my $self = shift;
    my $line = shift;
    my $ret;

    $ret = "</FONT></FONT>\n";

    return $ret;
}

sub addErrorLog {
    my $self = shift;
    my $line = shift;
    my $code  = ( shift or $? );

    my $ret;

    $ret  = "<BR><BR>$line<BR><BR>\n";
    $ret .= "<TT><FONT SIZE=-1 COLOR=red>";
    $ret .= "<PRE>$code</PRE></FONT></TT>\n";

    return $ret;
}

sub addLogLine {
    my $self = shift;
    my $line = shift;
    my $ret;

    $ret  = "$line<BR>\n";

    return $ret;
}

sub addPreLogLine {
    my $self = shift;
    my $line = shift;
    my $ret;

    $ret  = "<TT><FONT SIZE=-1 COLOR=#445567>";
    $ret .= "<PRE>$line</PRE></FONT></TT>\n";

    return $ret;
}

##################################
##      internal functions      ##
##################################

sub getCopyRight {

    my $ret = "";
    global ($main::PRG, $main::VER);

    ## Close the Table
    $ret .= "<CENTER>";
    $ret .= "&copy; 1998-2003 by Massimiliano Pala and the OpenCA Group.";
    $ret .= "<BR>$main::PRG - Version $main::VER";
    $ret .= "</CENTER>\n";

    return $ret;
}

sub closePage {

    print $STDOUT "\n\n";
    print $STDOUT "</PRE><CENTER><HR WIDTH=80%></CENTER>\n";
    print $STDOUT "<FONT SIZE=\"+0\">";
    ## print $STDOUT getCopyRight();

    print $STDOUT "\n</BODY>\n";
    print $STDOUT "</HTML>\n";

    return 1;
}

## BUG NOTICE
## FIXME: HACK until there is OpenCA::Utilities
sub i18nGettext {

    my $i18n_string = gettext ($_[0]);

    my $i = 1;
    my $option;
    my $value;
    while ($_[$i]) {
        $i18n_string =~ s/$_[$i]/$_[$i+1]/g;
        $i += 2;
    }

    return $i18n_string;
}

1;
