package WebUtils;
require Exporter;
@ISA = qw(Exporter);

  use strict;
  use Text::Template;
  use CGI;
  use CGI::Carp qw(carpout);
  use HTML::PageIndex;
  use Date::Parse;
  use Date::Format;
  use MIME::Lite;
  use HTML::Entities;


sub fatalError {

  my ($errorName,$errorString,$loadTemplate,$headerFileName,$errorData) = @_;

  my %io = ();

  if ($loadTemplate == 1) {

     $io{'title'} = 'Error';

     templateCall("$headerFileName",undef,undef,\%io);

  }

  if ($errorName ne '')   { $io{'errorName'} = $errorName; }
  if ($errorString ne '') { $io{'errorString'} = $errorString; }

  templateCall('/home/webutils/templates/error.cgi.html',undef,1,\%io,$errorData);

  exit(0);

}


sub buildCallsToJS {

  my $calls       = undef;
  my (@filePaths) = @_;

  foreach my $file (@filePaths) {

    $calls .= qq[
    <script type="text/javascript" src="$file"></script>
    ];

  }

  return $calls;

}


sub templateCall {

  # Version 2.03
  # Changes from Version 2.02
  #   - More template path flexibility
  #   - Fixed error reporting
  # Version 2.02
  # Changes from Version 2.01
  #   - Supports 4 Hashes now
  # Changes from Version 2.00
  #   - Added $WebVariables::basepath variable. Must be passed to function
  # Supports up to 3 hashes

  my ($templateFile,$return,$base,@content) = @_;
  my ($filename);

  # Determines where the base path is

  if ($base == 1) { # Full path of the template must be specified

    $filename = "$templateFile";

  } elsif ($base == 2) { # 'half' path must be specified

    $filename = "$WebVariables::publicdir/$templateFile";

  } else {

    $filename = "$WebVariables::basepath/templates/$templateFile";

  }

  my ($content1,$content2,$content3,$content4,$content5) = @content;

  my $template = new Text::Template ( TYPE => 'FILE', SOURCE => $filename ) or die $Text::Template::ERROR ;

  my $text;

  if ($content1) {

    $text = $template->fill_in(HASH => [$content1,$content2,$content3,$content4,$content5]);

  } else {

    $text = $template->fill_in();

  }

  # Returns the template as a variable or prints it out
  if ($return) { return $text } else { print "$text" }

}

sub perpage {

  # Version 1.00

  my ($entries,$entryperpage,$currentPage) = @_;

     # This section calculates how many pages are to be used
  my $pages = $entries/$entryperpage;
     $pages = int($pages);
  my $remainder = $entries % $entryperpage;

  if ($remainder && $pages) {

     $pages++;

  }

     # Finds out what the current page is

  if (!($currentPage)) {

     $currentPage = 1;

  }

  my $thisstart = (($currentPage - 1) * $entryperpage);
  my $thisstop  = ($thisstart + $entryperpage) - 1;

  if ($thisstop > $entries) {

     $thisstop=$entries;

  }

  return($thisstart,$thisstop,$pages,$currentPage);

} # End Sub


sub metaRedirect {

  # Version 1.01

    # - Corrected meta tag for XHTML compliance

  # Version 1.00

  my $secondsDelay = $_[0];
  my $url          = $_[1];
  my $message      = $_[2];

  print qq[

    <meta http-equiv="Refresh" content="$secondsDelay;url=$url" />

    <p>$message</p>

  ];


}


sub jsRedirect {

  # Version 1.00

  my $URL = $_[0];

  print qq[<script type="text/javascript">
             window.location = "$URL";
             </script>];

}


sub prepareInsert {

  # Version 1.00

  use CGI qw/:standard/;

  my (@fields) = @_;
  my ($values,$temp);

  foreach (@fields) {

    $temp    = join(",",param($_));
    $temp   =~ s/\'/\\'/g;
    $values .= "'$temp', ";

  }

  chop $values;chop $values;

  return $values;

}


sub prepareUpdate {

  # Version 1.00

  use CGI qw/:standard/;

  my (@fields) = @_;
  my ($values,$temp);

  foreach (@fields) {

    $temp    = join(",",param($_));
    $temp   =~ s/\'/\\'/g;
    $values .= "$_='$temp', ";

  }

  chop $values;
  chop $values;

  return $values;

}


sub cleanDate {

  # Version 2.00

    # Added timezone option

  # Version 1.00

  my $zone = undef;

  my ($date,$template,$timezone) = @_;

  if ($timezone) { $zone = ", $timezone"; }

     $date = str2time("$date $zone");
     $date = time2str($template,"$date $zone");

  return ($date);

}


sub sanitise  {

  # Version 1.00

  my $string = shift;

  $string =~ tr/\x91\x92\x93\x94\x96\x97/''""\-\-/;
  $string =~ s/\x85/.../sg;
  $string =~ tr/[\x80-\x9F]//d;

  return($string);
}


sub getDateRange {

  # Variables passed
  # Request Type     - Can be either 'html' or 'script'
  # yearRequired     - What year you want to search for
  # yearsBack        - How many years back do you want to search
  # dateFieldName    - What is the field name for the SQL search (only applicable to 'script' Request Type)
  # indentSpacesHtml - Allows you to align this generated code with the rest of your page (only applicable to 'html' Request Type)
  # typeText         - Allows you to use this module for any archiving system. Ie. events, courses, document repository
  # financialYear    - Instead of displaying just the year eg 2006 it will show 2006-2007
  my ($requestType,$yearRequired,$yearsBack,$dateFieldName,$indentSpacesHtml,$typeText,$financialYear) = @_ ;

  my $currYear = time2str("%Y",time()) ;
  if ($financialYear) {

    my $monthInt = time2str("%m",time());
    if ($monthInt < 7) { $currYear-- }

  }

  my ($dateRange,$dateText,$dateHTML,$whitespace);

  # Generate spaces for html formatting
  if ($indentSpacesHtml) { foreach (my $i = 0; $i < $indentSpacesHtml; $i++) { $whitespace .= ' ' } }

  for (my $i = $currYear; $i >= $currYear - $yearsBack ; $i--) {

    my $curFinancialYear = $i + 1 ;
    $curFinancialYear    = qq[$i - $curFinancialYear] ;

    # Routines for script
    if ($yearRequired == 1 )     { $dateRange = "'01-01-$currYear' AND $dateFieldName < CURRENT_DATE";
                                   $dateText = "Previous $typeText this year" }
    elsif ($yearRequired == $i)  { $dateRange = qq['01-01-$i' AND $dateFieldName < '01-01-] . ($i + 1) . "'" ;
                                   $dateText = qq[$typeText from $i] }
    # Routines for html
    my ($selectedPastCourses,$selected) = (undef,undef) ;
    if ($yearRequired == 1 )  { $selectedPastCourses = qq[ selected="selected"] }
    if ($yearRequired == $i ) { $selected            = qq[ selected="selected"] }

    if ($financialYear) {

      if ($i == $currYear) {
        $dateHTML .= qq[\n$whitespace<option value="1"$selectedPastCourses>Past $typeText this year</option>];
      } else {
        $dateHTML .= qq[\n$whitespace<option value="$i"$selected>$curFinancialYear</option>];
      }

    } else {

      if ($i == $currYear) {
        $dateHTML .= qq[\n$whitespace<option value="1"$selectedPastCourses>Past $typeText this year</option>];
      } else {
        $dateHTML .= qq[\n$whitespace<option value="$i"$selected>$i</option>];
      }

    }

  }

  if (!$dateRange) { $dateRange=qq[CURRENT_DATE AND $dateFieldName < (CURRENT_DATE::date + interval '1 year')::date]; $dateText = "Upcoming $typeText" }

  # Return variables depending on what request type was called
  if ($requestType eq 'script') { return ($dateRange,$dateText) } elsif ($requestType eq 'html') { return ($dateHTML) }


} # End Sub

# ADD COMMAS TO INTEGERS
sub commify {
  local $_  = shift;
  1 while s/^(-?\d+)(\d{3})/$1,$2/;
  return $_;
}


sub buildSimpleSelect {

  my ($dbh,$table,$field,$id,$orderField,$orderDirection,$disableID,$regExp) = @_;

  $orderField     = $field if (!$orderField)     ; # Defaults to the selected viewing field
  $orderDirection = 'ASC'  if (!$orderDirection) ; # Can take values of ASC / DESC
  $disableID      = 0      if (!$disableID)      ; # You can compare the selected value as your custom field instead of id

  my $cmdSelect = qq[

    SELECT id,$field
      FROM $table
    ORDER BY $orderField $orderDirection

  ];

  my $simpleSelect = $dbh->selectall_arrayref($cmdSelect) or WebUtils::fatalError('dbError',$DBI::errstr);

  my $option = undef;

  foreach my $array (@$simpleSelect) {

    my $selected = undef;

    if ($regExp) {

      if    ($array->[$disableID] =~ /$id/) { $selected = ' selected="selected"' }

    } elsif ($id == $array->[$disableID])   { $selected = ' selected="selected"' }

    $array->[1] = encode_entities($array->[1]);

    $option .= qq[                          <option value="$array->[$disableID]"$selected>$array->[1]</option>\n];

  }

  return ($option);

}

sub securityQA {

  my ($dbh,$questionOrAnswer,$security_id,$security_answer) = @_ ;

  my ($where,$where_placeholder) = (undef,undef) ;
  if ($questionOrAnswer eq 'answer') {
    $where = qq[WHERE id = ? AND lower(answer) = ? ] ;
  }

  my $cmdSecurity = qq[

    SELECT
      id,question
    FROM
      security_qa
    $where
    ORDER BY
      random()
    LIMIT 1

  ] ;

  my ($id,$question) = (undef,undef);
  if ($questionOrAnswer eq 'question') {
    ($id,$question) = $dbh->selectrow_array($cmdSecurity) or die $DBI::errstr  ;
  } else {
    ($id,$question) = $dbh->selectrow_array($cmdSecurity,undef,$security_id,lc($security_answer)) ;
  }

  return($id,$question) ;

}
