package MySQL::Admin::GUI;
use strict;
use warnings;
use utf8;
use DBI::Library::Database qw(:all);
use MySQL::Admin::Main qw(:all);
use CGI::QuickFormR;
use HTML::TabWidget qw(:all);
use HTML::Window qw(:all);
use HTML::Menu::Pages;
use MySQL::Admin qw(:all :lze :cgi-lib);
use HTML::Menu::TreeView qw(:all);
use HTML::Entities;
use HTML::Editor;
use HTML::Editor::BBCODE;
use URI::Escape;
use User::pwent;
use MySQL::Admin::Settings;
use MySQL::Admin::Translate;
use MySQL::Admin::Config;
use MySQL::Admin::Session;
use MySQL::Admin::Actions;
use Authen::Captcha;
use Encode;
use Fcntl qw(:flock);
use Symbol;

use CGI::Carp qw(fatalsToBrowser);
require Exporter;
use vars qw(
  $DefaultClass
  $ACCEPT_LANGUAGE
  @EXPORT
  @ISA
  @m_aCookies
  @m_aTree
  @m_aT1
  $m_bMod_perl
  $m_bUpload_error
  %m_hUniq
  $m_hrAct
  $m_hrParams
  $m_hrSettings
  $m_hrLng
  $m_nStart
  $m_nEnd
  $m_nRight
  $m_nSize
  $m_nUplod_bytes
  $m_oDatabase
  $m_dbh
  $m_sAction
  $m_sFile
  $m_sSid
  $m_sStyle
  $m_sSub
  $m_sTitle
  $m_sUser
  $m_sContent
  $m_sCurrentDb
  $m_sCurrentHost
  $m_sCurrentUser
  $m_sCurrentPass
);
@MySQL::Admin::GUI::EXPORT  = qw(action ContentHeader Body maxlength openFile ChangeDb action Unique applyRights);
@ISA                        = qw(Exporter MySQL::Admin);
$MySQL::Admin::GUI::VERSION = '0.6';
$m_bMod_perl                = ($ENV{MOD_PERL}) ? 1 : 0;
local $^W = 0;

=head1 NAME

MySQL::Admin::GUI - MySQL User front end

=head1 SYNOPSIS

        use MySQL::Admin::GUI;
        ContentHeader("config/settings.pl");
        print Body();


=head2 EXPORT

        action Body maxlength openFile

=cut

=head2 ContentHeader()

     ContentHeader("/path/to/your/settings.pl");

=cut

sub ContentHeader
{
    my $m_hrSettingsfile = shift;
    init($m_hrSettingsfile);
    loadActions($m_hrSettings->{actions});
    *m_hrAction  = \$MySQL::Admin::Actions::actions;
    $m_oDatabase = new DBI::Library::Database();
    $m_oDatabase->rewrite($m_hrSettings->{cgi}{mod_rewrite});
    $m_oDatabase->serverName($m_hrSettings->{cgi}{serverName});
    $m_oDatabase->floodtime($m_hrSettings->{floodtime});
    $m_dbh = $m_oDatabase->initDB(
                                  {
                                   name     => $m_hrSettings->{database}{name},
                                   host     => $m_hrSettings->{database}{host},
                                   user     => $m_hrSettings->{database}{user},
                                   password => $m_hrSettings->{database}{password},
                                  }
    );
    $m_sCurrentDb =
        param('m_ChangeCurrentDb')
      ? param('m_ChangeCurrentDb')
      : $m_hrSettings->{database}{CurrentDb};
    $m_sAction = param('action') ? param('action') : $m_hrSettings->{defaultAction};
    $m_sAction =
      ($m_sAction =~ /^(\w{3,50})$/)
      ? $1
      : $m_hrSettings->{defaultAction};
    $m_sCurrentHost =
        param('m_shost')
      ? param('m_shost')
      : $m_hrSettings->{database}{CurrentHost};
    $m_sCurrentUser =
        param('m_suser')
      ? param('m_suser')
      : $m_hrSettings->{database}{CurrentUser};
    $m_sCurrentPass =
        param('m_spass')
      ? param('m_spass')
      : $m_hrSettings->{database}{CurrentPass};

    if (param('m_ChangeCurrentDb')) {
        $m_hrSettings->{database}{CurrentDb}   = $m_sCurrentDb;
        $m_hrSettings->{database}{CurrentHost} = $m_sCurrentHost;
        $m_hrSettings->{database}{CurrentUser} = $m_sCurrentUser;
        $m_hrSettings->{database}{CurrentPass} = $m_sCurrentPass;
        $m_sAction                             = 'ShowTables';
        saveSettings($m_hrSettingsfile);
    }
    my $cookiepath = $m_hrSettings->{cgi}{cookiePath};
    $m_nSize =
        cookie(-name => 'size')
      ? cookie(-name => 'size')
      : $m_hrSettings->{size};
    if (param('size')) {
        $m_nSize = param('size') =~ /(16|22)/ ? $1 : $m_nSize;
    }
    size($m_nSize);
    my $cook = cookie(
                      -name    => 'size',
                      -value   => "$m_nSize",
                      -expires => '+1y',
                      -path    => "$cookiepath"
    );
    push @m_aCookies, $cook;
    undef $m_sSid;
    if ($m_sAction eq 'rss') {print $m_oDatabase->rss("news", 0);}
    else {

        if ($m_sAction eq 'logout') {
            my $cookie = cookie(
                                -name    => 'sid',
                                -value   => "",
                                -expires => '-1d',
                                -path    => "$cookiepath"
            );
            push @m_aCookies, $cookie;
            print header(-charset => 'UTF-8',
                         -cookie  => [@m_aCookies]);
            $m_sUser = 'guest';
            $m_sSid  = '123';
        } elsif ($m_sAction eq 'login') {
            my $ip = remote_addr();
            my $u  = param('user');
            my $p  = param('pass');
            if (defined $u && defined $p && defined $ip) {
                use MD5;
                my $md5 = new MD5;
                $md5->add($u);
                $md5->add($p);
                my $cyrptpass = $md5->hexdigest();
                if ($m_oDatabase->checkPass($u, $cyrptpass)) {
                    $m_sSid = $m_oDatabase->setSid($u, $p, $ip);
                    my $cookie = cookie(
                                        -name    => 'sid',
                                        -value   => "$m_sSid",
                                        -path    => "$cookiepath",
                                        -expires => '+1y'
                    );
                    push @m_aCookies, $cookie;
                    print header(-charset => 'UTF-8',
                                 -cookie  => [@m_aCookies]);
                } else {
                    print header(-charset => 'UTF-8',
                                 -cookie  => [@m_aCookies]);
                    print translate("wrongpass"), '&#160;',
                      a(
                        {
                         href  => "$ENV{SCRIPT_NAME}?action=lostpass",
                         class => "treeviewLink2"
                        },
                        translate("lostpass")
                      );
                }
            } else {
                print header(-charset => 'UTF-8',
                             -cookie  => [@m_aCookies]);
            }
        } else {
            $m_sSid = cookie(-name => 'sid') ? cookie(-name => 'sid') : '123';
            print header(-charset => 'UTF-8',
                         -cookie  => [@m_aCookies]);
        }
    }
}

=head2 Body()

     print Body();

=cut

sub Body
{
    $m_sStyle = $m_hrSettings->{cgi}{style};
    $m_sUser =
      defined $m_oDatabase->getName($m_sSid)
      ? $m_oDatabase->getName($m_sSid)
      : 'guest';
    $m_nStart = param('von') ? param('von') : 0;
    $m_nStart = ($m_nStart =~ /^(\d+)$/) ? $1 : 0;
    my $newslength = $m_oDatabase->tableLength('news', $m_nRight);
    $m_nEnd = param('bis') ? param('bis') : ($newslength > 9) ? 10 : $newslength;
    $m_nEnd = ($m_nEnd =~ /^(\d+)$/) ? $1 : 0;
    if ($m_nStart < 0) {
        $m_sAction = 'exploit';
        $m_nStart  = 0;
        $m_nEnd    = $newslength;
    }
    if (param('include')) {
        session();
        $m_hrAct = $m_hrParams;
    } else {
        $m_hrAct = $m_oDatabase->getAction($m_sAction);
    }
    $m_hrAct =
      defined $m_hrAct
      ? $m_hrAct
      : $m_oDatabase->getAction($m_hrSettings->{'defaultAction'});
    $m_sTitle = $m_hrAct->{'title'};
    $m_sFile  = $m_hrAct->{'file'};
    $m_sSub   = $m_hrAct->{'sub'};
    $m_nRight =
        $m_oDatabase->userright($m_sUser)
      ? $m_oDatabase->userright($m_sUser)
      : 0;
    my $logIn;
    if ($m_sUser eq 'guest') {
        my $link =
          $m_hrSettings->{cgi}{mod_rewrite}
          ? "/reg.html"
          : "$ENV{SCRIPT_NAME}?action=reg";
        my %vars = (
                    user   => 'guest',
                    action => 'login',
        );
        my $qstring  = createSession(\%vars);
        my $register = translate('register');

        #todo template
        $logIn = qq(
<form  action=""  target="_parent" method="post"  name="Login" onsubmit="return checkLogin()">
<input type="hidden" name="action" value="login"/>
<table align="left" border="0" cellpadding="2" cellspacing="0" summary="login" class="LoginLayout" width="*"><tr>
<td>Name:</td>
<td><input  type="text" id="user" name="user" value=""  maxlength="15" alt="" align="left"/></td>
<td>Password:</td>
<td><input style="" type="password" id="password" name="pass" value ="" maxlength="15" alt="" align="left"/></td><td><input type="submit"  name="submit" value="Login"  alt=""/></td><td><a  href="$link" class="menuLink">$register</a></td></tr></table>
</form>
);
    } else {
        my $lg =
          $m_hrSettings->{cgi}{mod_rewrite}
          ? '/logout.html'
          : "$ENV{SCRIPT_NAME}?action=logout";
        my $wlc = translate('welcome');
        my $lgo = translate('logout');
        $logIn = qq(
<table align="left" border="0" cellpadding="2" cellspacing="0" summary="contentHeader" class="contentHeader" width="*"><tr>
<td>$wlc,</td><td valign="top">$m_sUser</td><td><a class="menuLink" href="$lg">logout</a></td></tr></table>
);
    }
    my $z       = $m_nSize == 16 ? 'plus.png' : 'minus.png';
    my $newsize = $m_nSize == 16 ? 22         : 16;
    my $lk2 =
      $m_hrSettings->{cgi}{mod_rewrite}
      ? "/news.html&amp;size=$newsize;"
      : "$ENV{SCRIPT_NAME}?action=news&amp;size=$newsize;";
    my $zoom = qq(<img src="/images/$z" style="cursor:pointer;" alt=""  border="0" onclick="location.href='$lk2'"/>);
    my $query = param('query') ? param('query') : '';
    my %set = (
               zoom      => $zoom,
               path      => "$m_hrSettings->{cgi}{bin}/templates",
               style     => $m_sStyle,
               title     => translate($m_sTitle),
               server    => $m_hrSettings->{cgi}{'serverName'},
               login     => $logIn,
               size      => $m_nSize,
               right     => $m_nRight,
               query     => $query,
               htmlright => $m_hrSettings->{htmlright},
               template  => 'blog.htm'
    );
    initMain(\%set);
    $m_sContent = '';
    $m_sContent .= Header();
    $m_sContent .= '<table align="center" border="0" cellpadding="0" cellspacing="0" summary="contentLayout"  class="contentLayout" width="100%"><tr>';

    if ($m_hrSettings->{sidebar}{left}) {
        $m_sContent .= '<td  valign="top" class="leftSidebar">';
        my @lboxes = $m_oDatabase->fetch_AoH("select * from box where `position` = 'left' && `right` <= '$m_nRight'");
        $m_sContent .= '<table  border="0" cellpadding="0" cellspacing="0" summary="contentLayout" class="contentLayout" width="100%">';
        foreach (my $i = 0; $i <= $#lboxes; $i++) {
            do("$m_hrSettings->{cgi}{bin}/Sidebar/$lboxes[$i]->{file}");
            warn "Error : $@ " if ($@);
        }
        if (defined $m_hrAct->{box}) {
            my @boxes = split /;/, $m_hrAct->{box};
            foreach my $box (@boxes) {
                my $bx = $m_oDatabase->fetch_hashref("select * from box where `dynamic` = 'left' && `file` = '$box.pl' && `right` <= '$m_nRight'");
                do("$m_hrSettings->{cgi}{bin}/Sidebar/$bx->{file}") if (defined $bx->{file} && -e "$m_hrSettings->{cgi}{bin}/Sidebar/$bx->{file}");
                warn "Error : $@ " if ($@);
            }
        }
        $m_sContent .= '</table>';
        $m_sContent .= '</td>';
    }
    $m_sContent .= '<td align="center" valign="top" class="content">';
    my %parameter = (
                     path        => "$m_hrSettings->{cgi}{bin}/templates/",
                     style       => $m_sStyle,
                     action      => $m_sAction,
                     file        => $m_sFile,
                     right       => $m_nRight,
                     mod_rewrite => $m_hrSettings->{cgi}{mod_rewrite},
                     template    => 'lzetabwidget.htm',
                     action      => $m_sAction,
                     scriptname  => $ENV{SCRIPT_NAME},
    );
    my $sth = $m_dbh->prepare("select title,action,src from `topnavigation` where `right` <= $m_nRight");
    $sth->execute() or warn "select title,action,src from `topnavigation` where `right` <= $m_nRight" . $m_dbh->errstr;
    my $hasCurrentlink = 0;
    while (my @a = $sth->fetchrow_array()) {
        my $fm =
          ($m_hrSettings->{cgi}{mod_rewrite})
          ? "/$a[1].html"
          : "$ENV{SCRIPT_NAME}?action=$a[1]";
        my $nm = 'link';
        if ("$a[1].pl" eq $m_sFile) {
            $nm             = 'currentLink';
            $hasCurrentlink = 1;
        }
        push @{$parameter{anchors}},
          {
            class => $nm,
            style => $m_sStyle,
            text  => translate($a[0]),
            href  => $fm,
            src   => $a[2],
            title => translate($a[0])
          };
    }
    unless ($hasCurrentlink) {
        if (param('include')) {
            push @{$parameter{anchors}},
              {
                text  => translate($m_hrAct->{title}),
                class => 'currentLink',
                style => $m_sStyle,
                href  => "javascript:void(0)",
                title => translate($m_hrAct->{title})
              };
        } else {
            $sth = $m_dbh->prepare("select title from actions where `action` =  ?");
            $sth->execute($m_sAction) or warn $m_dbh->errstr;
            my @a1 = $sth->fetchrow_array();
            push @{$parameter{anchors}},
              {
                text  => translate($a1[0]),
                class => 'currentLink',
                style => $m_sStyle,
                href  => 'javascript:void(0)',
                title => translate($a1[0])
              };
        }
    }
    push @{$parameter{anchors}},
      {
        text  => translate('Action'),
        href  => 'javascript:void(0)',
        id    => 'dropdownLink',
        class => 'adminlink',
        title => translate('Action'),
      } if ($m_nRight >= 5);
    push @{$parameter{anchors}},
      {
        text  => translate('showwindow'),
        href  => 'javascript:displayWindows();',
        class => 'javaScriptLink',
        title => translate('showwindow')
      };
    $m_sContent .= Menu(\%parameter);
    $m_sContent .= tabwidgetHeader();
    if ($m_nRight >= $m_hrAct->{right}) {
        if (defined $m_sFile and defined $m_sSub) {
            if (param('include')) {
                my $qstring = param('include') ? param('include') : 0;
                CGI::upload_hook(\&hook);
                if (defined $qstring) {
                    session($qstring);
                    if (defined $m_hrParams->{file} && defined $m_hrParams->{sub}) {
                        if (-e $m_hrParams->{file}) {
                            do("$m_hrParams->{file}");
                            eval($m_hrParams->{sub}) if $m_hrParams->{sub} ne 'main';
                            warn $@ if ($@);
                        } else {
                            do("$m_hrSettings->{cgi}{bin}/Content/exploit.pl");
                            warn $@ if ($@);
                        }
                    }
                }
            } else {
                do("$m_hrSettings->{cgi}{bin}/Content/$m_sFile");
                eval($m_sSub) if $m_sSub ne 'main';
                warn "Error : $@ " if ($@);
                $m_dbh = $m_oDatabase->initDB(
                                              {
                                               name     => $m_hrSettings->{database}{name},
                                               host     => $m_hrSettings->{database}{host},
                                               user     => $m_hrSettings->{database}{user},
                                               password => $m_hrSettings->{database}{password},
                                              }
                );
            }
        } else {
            do("$m_hrSettings->{cgi}{bin}/Content/news.pl");
            warn "Error : $@ " if ($@);
        }
    } else {
        do("$m_hrSettings->{cgi}{bin}/Content/exploit.pl");
        warn $@ if ($@);
    }
    $m_sContent .= br();
    $m_sContent .= tabwidgetFooter();
    $m_sContent .= '<br/></td>';
    if ($m_hrSettings->{sidebar}{right}) {
        $m_sContent .= '<td valign="top" class="rightSidebar">';
        $m_sContent .= '<table border="0" cellpadding="0" cellspacing="0" summary="contentLayout" class="contentLayout" width="100%">';
        my @rboxes = $m_oDatabase->fetch_AoH("select * from box where `position` = 'right' && `right` <= ? ", $m_nRight);
        for (my $i = 0; $i <= $#rboxes; $i++) {
            do("$m_hrSettings->{cgi}{bin}/Sidebar/$rboxes[$i]->{file}");
            warn "Error : $@ " if ($@);
        }
        if (defined $m_hrAct->{box}) {
            my @boxes = split /;/, $m_hrAct->{box};
            foreach my $box (@boxes) {
                my $bx = $m_oDatabase->fetch_hashref("select * from box where `dynamic` = 'right' && `file` = ? && `right` <= ? ", "$box.pl", $m_nRight);
                do("$m_hrSettings->{cgi}{bin}/Sidebar/$bx->{file}") if (defined $bx->{file} && -e "$m_hrSettings->{cgi}{bin}/Sidebar/$bx->{file}");
                warn "Error : $@ " if ($@);
            }
        }
        $m_sContent .= '</table>';
        $m_sContent .= '</td>';
    }
    $m_sContent .= '</tr></table>';
    clearSession();
    $m_sContent .= Footer();
    return $m_sContent;
}

=head2  maxlength()

     maxlength($length ,\$text);

=cut

sub maxlength
{
    my $maxWidth = shift;
    ++$maxWidth;
    my $txt = shift;
    if (length($$txt) > $maxWidth) {
        my $maxLength = $maxWidth;
        my $i++;
        while ($i < length($$txt)) {
            if (substr($$txt, $i, 1) eq "<") {
                $maxLength = $maxWidth;
                do {$i++} while (substr($$txt, $i, 1) ne ">" and $i < length($$txt));
            }
            if (substr($$txt, $i, 1) eq "&") {
                $maxLength = $maxWidth;
                do {$i++} while (substr($$txt, $i, 1) ne ";" and $i < length($$txt));
            }
            $maxLength = (substr($$txt, $i, 1) =~ /\S/) ? --$maxLength : $maxWidth;
            if ($maxLength eq 0) {
                substr($$txt, $i, 1) = " ";
                $maxLength = $maxWidth;
            }
            $i++;
        }
    }
}

=head2 openFile

        my $file = openFile("filename");

=cut

sub openFile
{
    my $file = shift;
    if (-e $file) {
        use Fcntl qw(:flock);
        use Symbol;
        my $fh = gensym;
        open $fh, $file or warn "$!: $file $/";
        seek $fh, 0, 0;
        my $lines;
        while (my $line = <$fh>) {
            $lines .= $line;
        }
        close $fh;
        return $lines;
    } else {
        warn "file exestiert nicht $/";
    }
}

=head2 action

        my %action = {

                title => '',

                src   => 'location',

                location => '',

                style => 'optional',

        };

        $m_sContent .= action{\%action);

=cut

sub action
{
    my $hash     = shift;
    my $m_sTitle = $hash->{title} if (defined $hash->{title});
    my $src      = $hash->{src} if (defined $hash->{src});
    my $location = $hash->{location} if (defined $hash->{location});
    my $m_sStyle = (defined $hash->{style}) ? $hash->{style} : $m_sStyle;
    return
qq(<table align ="left" border ="0" cellpadding ="0" cellspacing="0" summary="layoutMenuItem"><tr><td valign ="middle"><img src="/style/$m_sStyle/buttons/$src" width="20" height="20" border="0" alt="" title="$m_sTitle" style="cursor:pointer;font-size:14px;vertical-align:bottom;"/></td><td><a class="link" href="$location"  style='font-size:14px;vertical-align:bottom;'>$m_sTitle</a></td></tr></table>);
}

=head2 ChangeDb

        my %db = {

                name => '',

                host   => '',

                user => '',

                password => '',

       };

       ChangeDb(\%db);

=cut

sub ChangeDb
{
    my $hash = shift;
    my $m_sTitle = $hash->{title} if (defined $hash->{title});
    $m_dbh = $m_oDatabase->initDB(
                                  {
                                   name     => $hash->{name},
                                   host     => $hash->{host},
                                   user     => $hash->{user},
                                   password => $hash->{password},
                                  }
    );
}

=head2 Unique()

Gibt einen eindeutigen schlüssel zurück.

        $unique =Unique();

=cut

sub Unique
{
    my $unic;
    do {$unic = int(rand(1000000));} while (defined $m_hUniq{$unic});
    $m_hUniq{$unic} = 1;
    return $unic;
}

=head2 applyRights()

updates the user rights to a treeviewLink

        applyRights(\@tree);

=cut

sub applyRights
{
    my $t = shift;
    for (my $i = 0; $i < @$t; $i++) {
        my $r = defined @$t[$i]->{right} ? @$t[$i]->{right} : 0;
        if ($r > $m_nRight) {
            undef @$t[$i];
        } elsif (defined @{@$t[$i]->{subtree}}) {
            applyRights(\@{@$t[$i]->{subtree}});
        }
    }
}

=head1 SEE ALSO

L<CGI> L<MySQL::Admin>
L<DBI> L<DBI::Library> L<DBI::Library::Database>
L<MySQL::Admin::Main> L<HTML::TabWidget>
L<HTML::Window> L<HTML::Menu::Pages>
L<HTML::Menu::TreeView> L<HTML::Editor::BBCODE> L<HTML::Editor>

=head1 AUTHOR

Dirk Lindner <lze@cpan.org>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2005-2009 by Hr. Dirk Lindner

This program 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;
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 Lesser General Public License for more details.

=cut

1;
