# ==================================================================
# Gossamer Threads Module Library - http://gossamer-threads.com/
#
#       GT::SQL::Display::HTML
#       Author: Scott & Alex
#       $Id: Table.pm,v 1.26 2004/10/01 21:52:12 jagerman Exp $
#
# Copyright (c) 2004 Gossamer Threads Inc.  All Rights Reserved.
# ==================================================================
#
# Description:
#       HTML module that provides a set of method to control your
# user display in order to get rid of HTML coding inside CGI script.
#

package GT::SQL::Display::HTML::Table;
# ===============================================================
    use strict;
    use vars qw/@ISA $AUTOLOAD $VERSION $ERROR_MESSAGE $ATTRIBS $DEBUG $FONT %SIZE_FORMS/;
    use GT::SQL::Display::HTML;

    @ISA             = qw/GT::SQL::Display::HTML/;
    $FONT            = 'face="Tahoma,Arial,Helvetica" size=2';
    $VERSION         = sprintf "%d.%03d", q$Revision: 1.26 $ =~ /(\d+)\.(\d+)/;
    $DEBUG           = 0;
    $ERROR_MESSAGE   = 'GT::SQL';

    $ATTRIBS = {
        db          => undef, 
        input       => undef,
        code        => {},
        font        => $FONT,
        hide_timestamp  => 0,
        view_key    => 0,
        defaults    => 0,
        search_opts => 0,
        values      => {},
        multiple    => 0,
        table       => 'border=0 width=500',
        tr          => '',
        mode        => '',
        td          => 'valign=top align=left',
        extra_table => 1,
        col_font    => $FONT,
        val_font    => $FONT,
        hide        => [],
        skip        => [],
        view        => [],
        disp_form   => 1,
        disp_html   => 0,
        file_field  => 0,
        file_delete => 0,
        file_use_path => 0
    };


sub display_row {
# ---------------------------------------------------------------
# Display a record row as html.
#
    my ($self, $opts) = @_;
    $opts->{disp_form} = 0;
    $opts->{disp_html} = 1;
    return $self->_display_row ($opts || ());
}

sub display_row_cols {
# ---------------------------------------------------------------
# returns the <td></td> for each of the title names for columns
#
    my $self = shift;

# Initiate if we are passed in any arguments as options.
    if (@_) { $self->init (@_); }

# Get the column hash and primary key
    $self->{cols} = $self->{db}->cols unless exists $self->{cols};
    $self->{pk}   = [$self->{db}->pk] unless exists $self->{pk};

# Output
    my $out = '';

# Hide the primary keys.
    $self->{view_key} and push (@{$self->{view}}, @{$self->{pk}});

# Calculate the form values.
    my $values  = $self->_get_defaults;

# Now go through each column and print out a column row.
    my @cols   = $self->{db}->ordered_columns;
    my $script = GT::CGI->url();
    $script    =~ s/[\&;]?sb=([^&;]*)//g;
    my $sb     = $1;
    $script    =~ s/[\&;]?so=(ASC|DESC)//g;
    my $so     = $1;

    foreach my $col (@cols) {
        $out .= qq!\n\t<td><font $self->{col_font}><b>!;
        $out .= qq!<a href="$script&sb=$col&so=! . ( ( ( $col eq $sb ) and $so eq 'ASC' ) ? 'DESC' : 'ASC' ) . qq!">!;
        $out .= exists $self->{db}->{schema}->{cols}->{$col}->{form_display} ? $self->{db}->{schema}->{cols}->{$col}->{form_display} : $col;
        $out .= ( ( $col eq $sb ) ? ( ($so eq 'ASC') ? " ^" : " v" ) : '' ) . "</a>";
        $out .= qq!</b></font></td>\n!;
    }

    return $out;
}

sub _display_row {
# ---------------------------------------------------------------
# Handles displaying of a form or a record.
#
    my $self = shift;

# Initiate if we are passed in any arguments as options.
    if (@_) { $self->init (@_); }

# Get the column hash and primary key
    $self->{cols} = $self->{db}->cols unless exists $self->{cols};
    $self->{pk}   = [$self->{db}->pk] unless exists $self->{pk};

# Output
    my $out = '';

# Hide the primary keys.
    $self->{view_key} and push (@{$self->{view}}, @{$self->{pk}});

# Calculate the form values.
    my $values  = $self->_get_defaults;

# Now go through each column and print out a column row.
    my @cols = $self->{db}->ordered_columns;
    foreach my $col (@cols) {

# Run any code refs that have been setup.
        if (exists $self->{code}->{$col} and (ref $self->{code}->{$col} eq 'CODE')) {
            $out .= $self->{code}->{$col}->($self, $self->{cols}->{$col}, $values);
            next;
        }
        next if $self->_skip ($col);

# Set the form name (using increment for multiple if requested) and also the display name.
        my $field_name   = $self->{multiple} ? "$self->{multiple}-$col" : $col;
        my $display_name = exists $self->{cols}->{$col}->{form_display} ? $self->{cols}->{$col}->{form_display} : $col;
        my $value = $values->{$col};
        my $disp = $self->{disp_form} ? $self->_get_form_display ($col) : $self->_get_html_display ($col);

        $disp eq 'hidden' and push (@{$self->{hide}}, $col) and next;

        $out .= qq!\n\t<td valign=texttop><font $self->{col_font}>!;

# Get the column display subroutine
        $out .= $self->$disp( { name => $field_name, def => $self->{cols}->{$col}, value => $value });

        $out .= qq!</font></td>\n!;

    }

    return $out;
}

sub display {
# ---------------------------------------------------------------
# Display a record as html.
#
    my ($self, $opts) = @_;
    $opts->{disp_form} = 0;
    $opts->{disp_html} = 1;
    return $self->_display ($opts || ());
}

sub _display {
# ---------------------------------------------------------------
# Handles displaying of a form or a record.
#
    my $self = shift;

# Initiate if we are passed in any arguments as options.
    if (@_) { $self->init (@_); }

# Get the column hash, primary keys, and unique columns
    $self->{cols} = $self->{db}->cols unless exists $self->{cols};
    $self->{pk}   = [$self->{db}->pk] unless exists $self->{pk};

# Output
    my $out = '';

# Hide the primary keys.
    $self->{view_key} and push (@{$self->{view}}, @{$self->{pk}});

# Opening table.
    $self->{extra_table} and ($out .= "<table border=1 cellpadding=0 cellspacing=0><tr><td>");
    $out .= "<table $self->{table}>";

# Set the table widths depending on if we need a third column.
    my ($cwidth, $vwidth);
    if ($self->{search_opts}) { $cwidth = "30%"; $vwidth = "60%" }
    else                      { $cwidth = "30%"; $vwidth = "70%" }

# Calculate the form values.
    my $values  = $self->_get_defaults;

# Now go through each column and print out a column row.
    my @cols = $self->{db}->ordered_columns;
    foreach my $col (@cols) {
        
# Run any code refs that have been setup.
        if (exists $self->{code}->{$col} and (ref $self->{code}->{$col} eq 'CODE')) {
            $out .= $self->{code}->{$col}->($self, $self->{cols}->{$col}, $values);
            next;
        }
        next if $self->_skip ($col);

# Set the form name (using increment for multiple if requested) and also the display name.
        my $field_name   = $self->{multiple} ? "$self->{multiple}-$col" : $col;
        my $display_name = (exists $self->{cols}->{$col}->{form_display} and length $self->{cols}->{$col}->{form_display})
                               ? $self->{cols}->{$col}->{form_display} : $col;
        my $value = $values->{$col};
        my $disp = $self->{disp_form} ? $self->_get_form_display ($col) : $self->_get_html_display ($col);

        $disp eq 'hidden' and push (@{$self->{hide}}, $col) and next;
        $out .= "<tr $self->{tr}><td $self->{td} width='$cwidth'><font $self->{col_font}>$display_name</font></td><td $self->{td} width='$vwidth'><font $self->{val_font}>";

# Get the column display subroutine
        my $o = $self->$disp(
            {
                name  => (defined $field_name ? $field_name : ''),
                def   => $self->{cols}->{$col},
                value => (defined $value ? $value : '')
            },
            ($values || {}),
            $self
        );
        $out .= $o if defined $o;
        $out .= "</font></td>";

# Display any search options if requested.
        if ($self->{search_opts}) {
            $out .= qq~<td $self->{td} width="10%"><font $self->{val_font}>~;
            $out .= $self->_mk_search_opts({
                name   => $field_name,
                def    => $self->{cols}->{$col},
                pk     => $self->{db}->_is_pk($col),
                unique => $self->{db}->_is_unique($col)
            }) || '&nbsp;';
            $out .= "</font></td>";
        }
        $out .= "\n";
    }   
    $out .= "</table>\n";

    my %seen;
    foreach (@{$self->{hide}}) {
        next if $seen{$_}++;
        my $field_name = $self->{multiple} ? "$self->{multiple}-$_" : $_;
        my $val = $values->{$_};
        if (exists $self->{cols}->{$_}->{time_check} and $self->{cols}->{$_}->{time_check}) {
            $val ||= $self->_get_time ($self->{cols}->{$_});
        }
        defined $val or ($val = '');
        GT::SQL::Display::HTML::_escape(\$val); 
        $out .= qq~<input type="hidden" name="$field_name" value="$val">~; 
    }
    $self->{extra_table} and ($out .= "</td></tr></table>\n");
    return $out;
}

1;

__END__

=pod

# Options for display forms/views:
#       hide_timestamp  => 1        # Do not display timestamp fields.
#       search_opts     => 1        # Add search options boxes.
#       multiple        => 1        # Prepend $multiple- to column names.
#       defaults        => 1        # Use .def defaults.
#       values          => {}       # hash ref of values to use (overrides input)
#       table           => 'string' # table properties, defaults to 0 border.
#       tr              => 'string' # table row properties, defaults to none.
#       td              => 'string' # table cell properties, defaults to just aligns.
#       extra_table     => 0        # disable wrap form in extra table for looks.
#       col_font        => 'string' # font to use for columns, defaults to $FONT.
#       val_font        => 'string' # font to use for values, defaults to $FONT.
#       hide            => []       # display fields as hidden tags.
#       view            => []       # display fields as html with hidden tags as well.
#       skip            => []       # don't display array of column names.

=cut
