package TWiki::Plugins::EditTablePlugin;
#
# TWiki WikiClone ($wikiversion has version info)
#
# Copyright (C) 2002-2004 Peter Thoeny, Peter@Thoeny.com
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# 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 General Public License for more details, published at
# http://www.gnu.org/copyleft/gpl.html
#
# =========================
#
# This is the EditTablePlugin used to edit tables in place.
#
# Each plugin is a package that contains the subs:
#
#   $config->{TWiki}->{Plugins}->{EditTablePlugin}->initPlugin ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{user}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{installWeb} )
#   $config->{TWiki}->{Plugins}->{EditTablePlugin}->commonTagsHandler ( $text, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web} )
#   startRenderingHandler( $text, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web} )
#   outsidePREHandler    ( $text )
#   insidePREHandler     ( $text )
#   $config->{TWiki}->{Plugins}->{EditTablePlugin}->endRenderingHandler ( $text )
#
# initPlugin is required, all other are optional.
# For increased performance, DISABLE handlers you don't need.
#
# NOTE: To interact with TWiki use the official TWiki functions
# in the &TWiki::Func module. Do not reference any functions or
# variables elsewhere in TWiki!!


# =========================

# =========================

sub new { 
	my $dummy = shift;
	my $config = shift;
	unshift @_,$dummy ;

   my ( $proto ) =@_ ;
   my $class = ref($proto) || $proto ;
   my $self;

	$self->{config}=$config;
   bless ( $self );

	$self->init_config();

   return $self ;
}



sub init_config { 

   my $self = shift;
	my $config = $self->{config} ;


$config->{TWiki}->{Plugins}->{EditTablePlugin}->{VERSION} = '1.024';
$config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeStart} = "--EditTableEncodeStart--";
$config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeEnd}   = "--EditTableEncodeEnd--";
$config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefsInitialized}  = 0;
undef $config->{TWiki}->{Plugins}->{EditTablePlugin}->{table};

}# END of init_config

# =========================
sub initPlugin
{ 
   my $self = shift;
	my $config = $self->{config} ;


 
	 $config->{TWiki}->{Plugins}->{EditTablePlugin}->init_config () ;

    ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{user}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{installWeb} ) = @_;

    # check for Plugins.pm versions
    if( $config->{TWiki}->{Plugins}->{VERSION} < 1 ) {
        $config->{TWiki}->{Func}->writeWarning ( "Version mismatch between EditTablePlugin and Plugins.pm" );
        return 0;
    }

    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query} = $config->{TWiki}->{Func}->getCgiQuery ();
    if( ! $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query} ) {
        return 0;
    }

    # Get plugin debug flag
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{debug} = $config->{TWiki}->{Func}->getPreferencesFlag ( "EDITTABLEPLUGIN_DEBUG" );

    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefsInitialized} = 0;
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{renderingWeb} = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web};

    # Plugin correctly initialized
    $config->{TWiki}->{Func}->writeDebug ( "- $config->{TWiki}->{Plugins}->{EditTablePlugin}->initPlugin ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web}.$config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic} ) is OK" ) if $config->{TWiki}->{Plugins}->{EditTablePlugin}->{debug};

    # Initialize $config->{TWiki}->{Plugins}->{EditTablePlugin}->{table} such that the code will correctly detect when to
    # read in a topic.
    undef $config->{TWiki}->{Plugins}->{EditTablePlugin}->{table};
    return 1;
}

# =========================
sub extractParams
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my( $theArgs, $theHashRef ) = @_;

    my $tmp = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "header" );
    $$theHashRef{"header"} = $tmp if( $tmp );

    $tmp = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "footer" );
    $$theHashRef{"footer"} = $tmp if( $tmp );

    $tmp = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "headerislabel" );
    $$theHashRef{"headerislabel"} = $tmp if( $tmp );

    $tmp = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "format" );
    $tmp =~ s/^\s*\|*\s*//o;
    $tmp =~ s/\s*\|*\s*$//o;
    $$theHashRef{"format"} = $tmp if( $tmp );

    $tmp = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "changerows" );
    $$theHashRef{"changerows"} = $tmp if( $tmp );

    $tmp = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "quietsave" );
    $$theHashRef{"quietsave"} = $tmp if( $tmp );

    $tmp = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "helptopic" );
    $$theHashRef{"helptopic"} = $tmp if( $tmp );

    $tmp = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "editbutton" );
    $$theHashRef{"editbutton"} = $tmp if( $tmp );

    return;
}

# =========================
sub commonTagsHandler
{ 
   my $self = shift;
	my $config = $self->{config} ;


### my ( $text, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web} ) = @_;   # do not uncomment, use $_[0], $_[1]... instead

    $config->{TWiki}->{Func}->writeDebug ( "- EditTablePlugin::commonTagsHandler( $_[2].$_[1] )" ) if $config->{TWiki}->{Plugins}->{EditTablePlugin}->{debug};

    # Add style sheet for date calendar to skin if needed.
    # Handling of the common tags is done separately for the topic text and view skin
    # The following if statement must be done before the early escape.
    #
    # NOTE:
    # When adding a new button to the table that needs the table to be in the edit mode,
    # be sure to add it below.
    if( ( $_[0] =~ m/^[<][!]DOCTYPE/ ) &&
        ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etedit' ) || $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etaddrow' ) || $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etdelrow') ) &&
        (!($_[0] =~ m/calendar-system/) ) ) {

        my $string = " <link type=\"text/css\" rel=\"stylesheet\""
                   . " href=\"%PUBURL%/$config->{TWiki}->{Plugins}->{EditTablePlugin}->{installWeb}/EditTablePlugin/calendar-system.css\" />\n";
        $_[0] =~ s/([<]\/head[>])/$string$1/i;
    }

    return unless $_[0] =~ /%EDIT(TABLE|CELL){(.*)}%/os;

    unless( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefsInitialized} ) {
        $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefCHANGEROWS}           = $config->{TWiki}->{Func}->getPreferencesValue ("CHANGEROWS") ||
                    &TWiki::Func::getPreferencesValue("EDITTABLEPLUGIN_CHANGEROWS") || "on";
        $prefQUIETSAVE            = $config->{TWiki}->{Func}->getPreferencesValue ("QUIETSAVE") ||
                    &TWiki::Func::getPreferencesValue("EDITTABLEPLUGIN_QUIETSAVE") || "on";
        $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefEDITBUTTON}           = $config->{TWiki}->{Func}->getPreferencesValue ("EDITBUTTON") ||
                    &TWiki::Func::getPreferencesValue("EDITTABLEPLUGIN_EDITBUTTON") || "Edit table";
        $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefJSCALENDARDATEFORMAT} = $config->{TWiki}->{Func}->getPreferencesValue ("JSCALENDARDATEFORMAT") ||
                    &TWiki::Func::getPreferencesValue("EDITTABLEPLUGIN_JSCALENDARDATEFORMAT") || "%Y/%m/%d";
        $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefJSCALENDARLANGUAGE}   = $config->{TWiki}->{Func}->getPreferencesValue ("JSCALENDARLANGUAGE") ||
                    &TWiki::Func::getPreferencesValue("EDITTABLEPLUGIN_JSCALENDARLANGUAGE") || "en";
        $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefJSCALENDAROPTIONS}    = $config->{TWiki}->{Func}->getPreferencesValue ("JSCALENDAROPTIONS") ||
                    &TWiki::Func::getPreferencesValue("EDITTABLEPLUGIN_JSCALENDAROPTIONS") || "";
        $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefsInitialized} = 1;
    }

    my $theWeb = $_[2];
    my $theTopic = $_[1];
    my $result = "";
    my $tableNr = 0;
    my $rowNr = 0;
    my $enableForm = 0;
    my $insideTable = 0;
    my $doEdit = 0;
    my $cgiRows = -1;

    # appended stuff is a hack to handle EDITTABLE correctly if at end
    foreach( split( /\r?\n/, "$_[0]\n<nop>\n" ) ) {
        if( s/(\s*)%EDITTABLE{(.*)}%/$config->{TWiki}->{Plugins}->{EditTablePlugin}->handleEditTableTag ( $theWeb, $theTopic, $1, $2 )/geo ) {
            $enableForm = 1;
            $tableNr += 1;

            my $cgiTableNr = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'ettablenr' ) || 0;
            $cgiRows = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etrows' ) || -1;
            if( ( $cgiTableNr == $tableNr ) && ( "$theWeb.$theTopic" eq "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{web}.$config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic}" ) ) {

               if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etsave' ) ) {
                   # [Save table] button pressed
                   $config->{TWiki}->{Plugins}->{EditTablePlugin}->doSaveTable ( $theWeb, $theTopic, $tableNr, "" );   # never return
                   return; # in case browser does not redirect

               } elsif( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etqsave' ) ) {
                   # [Quiet save] button pressed
                   $config->{TWiki}->{Plugins}->{EditTablePlugin}->doSaveTable ( $theWeb, $theTopic, $tableNr, "on" );   # never return
                   return; # in case browser does not redirect

               } elsif( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etcancel' ) ) {
                   # [Cancel] button pressed
                   $config->{TWiki}->{Plugins}->{EditTablePlugin}->doCancelEdit ( $theWeb, $theTopic );            # never return
                   return; # in case browser does not redirect

               } elsif( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etaddrow' ) ) {
                   # [Add row] button pressed
                   $cgiRows++ if( $cgiRows >= 0 );
                   $doEdit = $config->{TWiki}->{Plugins}->{EditTablePlugin}->doEnableEdit ( $theWeb, $theTopic, 0 );
                   return unless( $doEdit );

               } elsif( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etdelrow' ) ) {
                   # [Delete row] button pressed
                   $cgiRows-- if( $cgiRows > 1 );
                   $doEdit = $config->{TWiki}->{Plugins}->{EditTablePlugin}->doEnableEdit ( $theWeb, $theTopic, 0 );
                   return unless( $doEdit );

               } elsif( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etedit' ) ) {
                   # [Edit table] button pressed
                   $doEdit = $config->{TWiki}->{Plugins}->{EditTablePlugin}->doEnableEdit ( $theWeb, $theTopic, 1 ); # never return if locked or no permission
                   return unless( $doEdit );
                   $cgiRows = -1; # make sure to get the actual number of rows
               }
            }
        }
        if( $enableForm ) {
            if( /^(\s*)\|.*\|\s*$/ ) {
                # found table row
                $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableStart ( $theWeb, $theTopic, $tableNr, $doEdit ) unless $insideTable;
                $insideTable = 1;
                $rowNr++;
                if( ( $doEdit ) && ( $cgiRows >= 0 ) && ( $rowNr > $cgiRows ) ) {
                    # deleted row
                    $rowNr--;
                    next;
                }
                s/^(\s*)\|(.*)/$config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableRow ( $1, $2, $tableNr, $cgiRows, $rowNr, $doEdit, 0 )/eo;

            } elsif( $insideTable ) {
                # end of table
                $insideTable = 0;
                if( ( $doEdit ) && ( $cgiRows >= 0 ) && ( $rowNr < $cgiRows ) ) {
                    while( $rowNr < $cgiRows ) {
                        $rowNr++;
                        $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableRow ( $theSp, "", $tableNr, $cgiRows, $rowNr, $doEdit, 0 ) . "\n";
                    }
                }
                $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableEnd ( $theWeb, $rowNr, $doEdit );
                $enableForm = 0;
                $doEdit = 0;
                $rowNr = 0;
            }
            if( /^\s*$/ ) {      # empty line
                if( $enableForm ) {
                    # empty %EDITTABLE%, so create a default table
                    $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableStart ( $theWeb, $theTopic, $tableNr, $doEdit );
                    $rowNr = 0;
                    if( $doEdit ) {
                       if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} ) {
                           $rowNr++;
                           $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableRow ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}, "", $tableNr, $cgiRows, $rowNr, $doEdit, 0 ) . "\n";
                        }
                        do {
                            $rowNr++;
                            $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableRow ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}, "", $tableNr, $cgiRows, $rowNr, $doEdit, 0 ) . "\n";
                        } while( $rowNr < $cgiRows );
                    }
                    $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableEnd ( $theWeb, $rowNr, $doEdit );
                    $enableForm = 0;
                }
                $doEdit = 0;
                $rowNr = 0;
            }
        }
        $result .= "$_\n";
    }
    $result =~ s|\n?<nop>\n$||o; # clean up hack that handles EDITTABLE correctly if at end
    $_[0] = $result;
}

# =========================
sub endRenderingHandler
{ 
   my $self = shift;
	my $config = $self->{config} ;


### my ( $text ) = @_;   # do not uncomment, use $_[0] instead

    $config->{TWiki}->{Func}->writeDebug ( "- EditTablePlugin::endRenderingHandler( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web}.$config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic} )" ) if $config->{TWiki}->{Plugins}->{EditTablePlugin}->{debug};

    # This handler is called by getRenderedVersion just after the line loop

    return unless $_[0] =~ /$config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeStart}/os;

    $_[0] =~ s/$config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeStart}(.*?)$config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeEnd}/$config->{TWiki}->{Plugins}->{EditTablePlugin}->decodeValue ($1)/geos;
}

# =========================
sub encodeValue
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my( $theText ) = @_;

    # WindRiver specific hack to remove SprPlugin rendering
    $theText =~ s/<a href="[\w\/]*sprreport[^>]*>(.*?) (.*?)<\/a>/$1$2/goi;

    # FIXME: *very* crude encoding to escape Wiki rendering inside form fields
    $theText =~ s/\./%dot%/gos;
    $theText =~ s/(.)/\.$1/gos;

    # convert <br /> markup to unicode linebreak character for text areas
    $theText =~ s/.<.b.r. .\/.>/&#10;/gos;
    return $theText;
}

# =========================
sub decodeValue
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my( $theText ) = @_;

    $theText =~ s/\.(.)/$1/gos;
    $theText =~ s/%dot%/\./gos;
    $theText =~ s/\&([^#a-z])/&amp;$1/go; # escape non-entities
    $theText =~ s/</\&lt;/go;             # change < to entity
    $theText =~ s/>/\&gt;/go;             # change > to entity
    $theText =~ s/\"/\&quot;/go;          # change " to entity

    return $theText;
}

# =========================
sub parseFormat
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my( $theFormat, $theTopic, $theWeb, $doExpand ) = @_;

    $theFormat =~ s/\$nop(\(\))?//gos;      # remove filler
    $theFormat =~ s/\$quot(\(\))?/\"/gos;   # expand double quote
    $theFormat =~ s/\$percnt(\(\))?/\%/gos; # expand percent
    $theFormat =~ s/\$dollar(\(\))?/\$/gos; # expand dollar
    if( $doExpand ) {
        # expanded form to be able to use %-vars in format
        $theFormat =~ s/<nop>//gos;
        $theFormat = $config->{TWiki}->{Func}->expandCommonVariables ( $theFormat, $theTopic, $theWeb );
    }
    my @aFormat = split( /\s*\|\s*/, $theFormat );
    $aFormat[0] = "text,16" unless @aFormat;
    return @aFormat;
}

# =========================
sub handleEditTableTag
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my( $theWeb, $theTopic, $thePreSpace, $theArgs ) = @_;

    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp} = $thePreSpace || "";
    %{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}} = (
        "header"        => "",
        "footer"        => "",
        "headerislabel" => "1",
        "format"        => "",
        "changerows"    => $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefCHANGEROWS},
        "quietsave"     => $prefQUIETSAVE,
        "helptopic"     => "",
        "editbutton"    => "",
    );

    my $iTopic = $config->{TWiki}->{Func}->extractNameValuePair ( $theArgs, "include" );
    if( $iTopic ) {
       # include topic to read definitions
       if( $iTopic =~ /^([^\.]+)\.(.*)$/o ) {
           $theWeb = $1;
           $iTopic = $2;
       }
       my $text = $config->{TWiki}->{Func}->readTopicText ( $theWeb, $iTopic );
       $text =~ /%EDITTABLE{(.*)}%/os;
       if( $1 ) {
           my $args = $1;
           if( "$theWeb.$iTopic" ne "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{web}.$config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic}" ) {
               # expand common vars, unless oneself to prevent recursion
               $args = $config->{TWiki}->{Func}->expandCommonVariables ( $1, $iTopic, $theWeb );
           }
           $config->{TWiki}->{Plugins}->{EditTablePlugin}->extractParams ( $args, \%{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}} );
       }
    }

    $config->{TWiki}->{Plugins}->{EditTablePlugin}->extractParams ( $theArgs, \%{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}} );

    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} = "" if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} =~ /^(off|no)$/oi );
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} =~ s/^\s*\|//o;
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} =~ s/\|\s*$//o;
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"headerislabel"} = "" if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"headerislabel"} =~ /^(off|no)$/oi );
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"footer"} = "" if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"footer"} =~ /^(off|no)$/oi );
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"footer"} =~ s/^\s*\|//o;
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"footer"} =~ s/\|\s*$//o;
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"changerows"} = "" if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"changerows"} =~ /^(off|no)$/oi );
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"quietsave"}  = "" if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"quietsave"}  =~ /^(off|no)$/oi );

    @{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{format}} = $config->{TWiki}->{Plugins}->{EditTablePlugin}->parseFormat ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"format"}, $theTopic, $theWeb, 0 );
    @{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{formatExpanded}} = $config->{TWiki}->{Plugins}->{EditTablePlugin}->parseFormat ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"format"}, $theTopic, $theWeb, 1 );
    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{nrCols} = @{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{format}};

    # FIXME: No handling yet of footer

    return "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<nop>";
}

# =========================
sub handleTableStart
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my( $theWeb, $theTopic, $theTableNr, $doEdit ) = @_;

    my $viewUrl = $config->{TWiki}->{Func}->getScriptUrl ( $theWeb, $theTopic, "viewauth" ) . "\#edittable$theTableNr";
    my $text = "";
    if( $doEdit ) {
        my $dir = "%PUBURL%/$config->{TWiki}->{Plugins}->{EditTablePlugin}->{installWeb}/EditTablePlugin";
        $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<script type=\"text/javascript\" src=\"$dir/calendar.js\"></script>\n";
        $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<script type=\"text/javascript\" src=\"$dir/calendar-"
               . "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefJSCALENDARLANGUAGE}.js\"></script>\n";
        $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<script type=\"text/javascript\" src=\"$dir/calendar-setup.js\"></script>\n";
    }
    $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<noautolink>\n" if $doEdit;
    $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<a name=\"edittable$theTableNr\"></a>\n";
    $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<form name=\"edittable$theTableNr\" action=\"$viewUrl\" method=\"post\">\n";
    $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<input type=\"hidden\" name=\"ettablenr\" value=\"$theTableNr\" />\n";
    $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<input type=\"hidden\" name=\"etedit\" value=\"on\" />\n" unless $doEdit;
    return $text;
}

# =========================
sub handleTableEnd
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my( $theWeb, $theRowNr, $doEdit ) = @_;

    my $text   = "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<input type=\"hidden\" name=\"etrows\"   value=\"$theRowNr\" />\n";
    if( $doEdit ) {
        # Edit mode
        $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<input type=\"submit\" name=\"etsave\"   value=\"Save table\" />\n";
        if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"quietsave"} ) {
            $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<input type=\"submit\" name=\"etqsave\"  value=\"Quiet save\" />\n";
        }
        if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"changerows"} ) {
            $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<input type=\"submit\" name=\"etaddrow\" value=\"Add row\" />\n";
            $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<input type=\"submit\" name=\"etdelrow\" value=\"Delete last row\" />\n"
              unless( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"changerows"} =~ /^add$/oi );
        }
        $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}<input type=\"submit\" name=\"etcancel\" value=\"Cancel\" />\n";

        if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"helptopic"} ) {
            # read help topic and show below the table
            if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"helptopic"} =~ /^([^\.]+)\.(.*)$/o ) {
                $theWeb = $1;
                $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"helptopic"} = $2;
            }
            my $helpText = $config->{TWiki}->{Func}->readTopicText ( $theWeb, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"helptopic"} );
                        #Strip out the meta data so it won't be displayed.
            $helpText =~ s/%META:[A-Za-z0-9]+{.*?}%//g;
            if( $helpText ) {
                $helpText =~ s/.*?%STARTINCLUDE%//os;
                $helpText =~ s/%STOPINCLUDE%.*//os;
                $text .= $helpText;
            }
        }

    } else {
        # View mode
        if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"editbutton"} eq "hide" ) {
            # do nothing, button assumed to be in a cell
        } else {
            # Add edit button to end of table
            $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}" . $config->{TWiki}->{Plugins}->{EditTablePlugin}->viewEditCell ( "editbutton, 1, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{'editbutton'}" );
        }
    }
    $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}</form>\n";
    $text .= "$config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}</noautolink>\n" if $doEdit;
    return $text;
}

# =========================
sub parseEditCellFormat
{ 
   my $self = shift;
	my $config = $self->{config} ;


    $_[1] = $config->{TWiki}->{Func}->extractNameValuePair ( $_[0] );
    return "";
}

# =========================
sub viewEditCell
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my ( $theAttr ) = @_;
    $theAttr = $config->{TWiki}->{Func}->extractNameValuePair ( $theAttr );
    return "" unless( $theAttr =~ /^editbutton/ );

    $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"editbutton"} = "hide" unless( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"editbutton"} ); # Hide below table edit button

    my @bits  = split( /,\s*/, $theAttr );
    my $value = "";  $value = $bits[2] if( @bits > 2);
    my $img   = "";  $img   = $bits[3] if( @bits > 3);

    unless( $value ) {
        $value = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefEDITBUTTON};
        $img = "";
        if( $value =~ s/(.+),\s*(.+)/$1/o ) {
            $img = $2;
            $img =~ s|%ATTACHURL%|%PUBURL%/$config->{TWiki}->{Plugins}->{EditTablePlugin}->{installWeb}/EditTablePlugin|o;
            $img =~ s|%WEB%|$config->{TWiki}->{Plugins}->{EditTablePlugin}->{installWeb}|o;
        }
    }

    if( $img ) {
        return "<input type=\"image\" src=\"$img\" alt=\"$value\" />";
    } else {
        return "<input type=\"submit\" value=\"$value\" />";
    }
}

# =========================
sub saveEditCellFormat
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my ( $theFormat, $theName ) = @_;
    return "" unless( $theFormat );
    $theName =~ s/cell/format/;
    return "<input type=\"hidden\" name=\"$theName\" value=\"$theFormat\" />";
}

# =========================
sub inputElement
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my ( $theTableNr, $theRowNr, $theCol, $theName, $theValue ) = @_;

    my $text = "";
    my $i = @{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{format}} - 1;
    $i = $theCol if( $theCol < $i );
    my @bits = split( /,\s*/, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{format}[$i] );
    my @bitsExpanded = split( /,\s*/, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{formatExpanded}[$i] );

    my $cellFormat = "";
    $theValue =~ s/\s*%EDITCELL{(.*?)}%/$config->{TWiki}->{Plugins}->{EditTablePlugin}->parseEditCellFormat ( $1, $cellFormat )/eo;
    $theValue = "" if( $theValue eq " " );
    if( $cellFormat ) {
        my @aFormat = $config->{TWiki}->{Plugins}->{EditTablePlugin}->parseFormat ( $cellFormat, $theTopic, $theWeb, 0);
        @bits = split( /,\s*/, $aFormat[0] );
        @aFormat = $config->{TWiki}->{Plugins}->{EditTablePlugin}->parseFormat ( $cellFormat, $theTopic, $theWeb, 1);
        @bitsExpanded = split( /,\s*/, $aFormat[0] );
    }

    my $type = "text";
    $type = $bits[0] if @bits > 0;
    # a table header is considered a label if read only header flag set
    $type = "label" if( ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"headerislabel"} ) && ( $theValue =~ /^\s*\*.*\*\s*$/ ) );
    $type = "label" if( $type eq "editbutton" );  # Hide [Edit table] button
    my $size = 0;
    $size = $bits[1] if @bits > 1;
    my $val  = "";
    my $valExpanded = "";
    my $sel  = "";
    my $style = "";
    $style = " style='background:#e8e8e8'" if ($theRowNr % 2);
    if( $type eq "select" ) {
        my $expandedValue = $config->{TWiki}->{Func}->expandCommonVariables ( $theValue, $theTopic, $theWeb );
        $size = 1 if $size < 1;
        $text = "<select$style name=\"$theName\" size=\"$size\">";
        $i = 2;
        while( $i < @bits ) {
            $val  = $bits[$i] || "";
            $valExpanded  = $bitsExpanded[$i] || "";
            if( $valExpanded eq $expandedValue ) {
                $text .= " <option selected=\"selected\">$val</option>";
            } else {
                $text .= " <option>$val</option>";
            }
            $i++;
        }
        $text .= " </select>";
        $text .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->saveEditCellFormat ( $cellFormat, $theName );

    } elsif( $type eq "row" ) {
        $size = $size + $theRowNr;
        $text = "$size<input type=\"hidden\" name=\"$theName\" value=\"$size\" />";
        $text .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->saveEditCellFormat ( $cellFormat, $theName );

    } elsif( $type eq "label" ) {
        # show label text as is, and add a hidden field with value
        my $isHeader = 0;
        $isHeader = 1 if( $theValue =~ s/^\s*\*(.*)\*\s*$/$1/o );
        $text = $theValue;

        # To optimize things, only in the case where a read-only column is
        # being processed (inside of this unless() statement) do we actually
        # go out and read the original topic.  Thus the reason for the
        # following unless() so we only read the topic the first time through.
        unless( defined $config->{TWiki}->{Plugins}->{EditTablePlugin}->{table} ) {
            # To deal with the situation where TWiki variables, like
            # %CALC%, have already been processed and end up getting saved
            # in the table that way (processed), we need to read in the
            # topic page in raw format
            my $topicContents = $config->{TWiki}->{Func}->readTopicText ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{web}, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{topic} );
            $config->{TWiki}->{Plugins}->{EditTablePlugin}->{table} = TWiki::Plugins::Table->new($config, $topicContents );
        }
        my $cell = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{table}->getCell( $theTableNr, $theRowNr - 1, $theCol );
        $theValue = $cell if( defined $cell );  # original value from file
        $theValue = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeStart} . $config->{TWiki}->{Plugins}->{EditTablePlugin}->encodeValue ( $theValue ) . $config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeEnd} unless( $theValue eq "" );
        $theValue = "\*$theValue\*" if( $isHeader );
        $text .= "<input$style type=\"hidden\" name=\"$theName\" value=\"$theValue\" />";
        $text = "\*$text\*" if( $isHeader );

    } elsif( $type eq "textarea" ) {
        my ($rows, $cols) = split( /x/, $size );
        $rows = 3 if $rows < 1;
        $cols = 30 if $cols < 1;

        $theValue = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeStart} . $config->{TWiki}->{Plugins}->{EditTablePlugin}->encodeValue ( $theValue ) . $config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeEnd} unless( $theValue eq "" );
        $text .= "<textarea$style rows=\"$rows\" cols=\"$cols\" name=\"$theName\">$theValue</textarea>";
        $text .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->saveEditCellFormat ( $cellFormat, $theName );

    } elsif( $type eq "date" ) {
        my $ifFormat = "";
        $ifFormat = $bits[3] if( @bits > 3 );
        $ifFormat = $ifFormat || $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefJSCALENDARDATEFORMAT};
        $size = 10 if $size < 1;
        $theValue = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeStart} . $config->{TWiki}->{Plugins}->{EditTablePlugin}->encodeValue ( $theValue ) . $config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeEnd} unless( $theValue eq "" );
        $text .= "<input type=\"text\" name=\"$theName\" id=\"id$theName\" size=\"$size\" value=\"$theValue\" />";
        $text .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->saveEditCellFormat ( $cellFormat, $theName );
        $text .= "<button type=\"reset\" id=\"trigger$theName\">...</button>";
        $text .= "<script type=\"text/javascript\">Calendar.setup({inputField : \"id$theName\", ifFormat ";
        $text .= ": \"$ifFormat\", button : \"trigger$theName\", singleClick : true $config->{TWiki}->{Plugins}->{EditTablePlugin}->{prefJSCALENDAROPTIONS} });</script>";

        $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->{'jscalendar'} = 1;

    } else { #  if( $type eq "text")
        $size = 16 if $size < 1;
        $theValue = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeStart} . $config->{TWiki}->{Plugins}->{EditTablePlugin}->encodeValue ( $theValue ) . $config->{TWiki}->{Plugins}->{EditTablePlugin}->{encodeEnd} unless( $theValue eq "" );
        $text = "<input$style type=\"text\" name=\"$theName\" size=\"$size\" value=\"$theValue\"/>";
        $text .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->saveEditCellFormat ( $cellFormat, $theName );
    }
    return $text;
}

# =========================
sub handleTableRow
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my ( $thePre, $theRow, $theTableNr, $theRowMax, $theRowNr, $doEdit, $doSave ) = @_;

    $thePre = "" unless( defined( $thePre ) );
    my $text = "$thePre\|";

    if( $doEdit ) {
        $theRow =~ s/\|\s*$//o;
        @cells = split( /\|/, $theRow );
        my $tmp = @cells;
        $config->{TWiki}->{Plugins}->{EditTablePlugin}->{nrCols} = $tmp if( $tmp > $config->{TWiki}->{Plugins}->{EditTablePlugin}->{nrCols} );  # expand number of cols
        my $val = "";
        my $cellFormat = "";
        my $cell = "";
        my $cellDefined = 0;
        my $col = 0;
        while( $col < $config->{TWiki}->{Plugins}->{EditTablePlugin}->{nrCols} ) {
            $col += 1;
            $cellDefined = 0;
            $val = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( "etcell${theRowNr}x$col" );
            $cellFormat = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( "etformat${theRowNr}x$col" );
            $val .= " %EDITCELL{$cellFormat}%" if( $cellFormat );
            if( defined $val ) {
                # change any new line character sequences to <br />
                $val =~ s/(\n\r?)|(\r\n?)+/<br \/>/gos;
                $cellDefined = 1;
                # Expand %-vars
                $cell = $val;
            } elsif( $col <= @cells ) {
                $cell = $cells[$col-1];
                $cellDefined = 1 if( length( $cell ) > 0 );
                $cell =~ s/^\s//o;
                $cell =~ s/\s$//o;
            } else {
                $cell = "";
            }
            if( ( $theRowNr <= 1 ) && ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} ) ) {
                unless( $cell ) {
                    if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} =~ /^on$/i ) {
                        if( ( @{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{format}} >= $col ) && ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{format}[$col-1] =~ /(.*?)\,/ ) ) {
                            $cell = $1;
                        }
                        $cell = "text" unless $cell;
                        $cell = "*$cell*";
                    } else {
                        my @hCells = split( /\|/, $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} );
                        $cell = $hCells[$col-1] if( @hCells >= $col );
                        $cell = "*text*" unless $cell;
                    }
                }
                $text .= "$cell\|";

            } elsif( $doSave ) {
                $text .= " $cell \|";

            } else {
                if( ( ! $cellDefined ) && ( @{$config->{TWiki}->{Plugins}->{EditTablePlugin}->{format}} >= $col )
                 && ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{format}[$col-1] =~ /^\s*(.*?)\,\s*(.*?)\,\s*(.*?)\s*$/ ) ) {
                     # default value of "| text, 20, a, b, c |" cell is "a, b, c"
                     # default value of "| select, 1, a, b, c |" cell is "a"
                     $val = $1;  # type
                     $cell = $3;
                     $cell = "" unless( defined $cell && $cell ne "" ); # Proper handling of "0"
                     $cell =~ s/\,.*$//o if( $val eq "select" || $val eq "date" );
                }
                $text .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->inputElement ( $theTableNr, $theRowNr, $col-1, "etcell${theRowNr}x$col", $cell ) . " \|";
            }
        }
    } else {
        $theRow =~ s/%EDITCELL{(.*?)}%/$config->{TWiki}->{Plugins}->{EditTablePlugin}->viewEditCell ($1)/geo;
        $text .= "$theRow";
    }
    return $text;
}

# =========================
sub doSaveTable
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my ( $theWeb, $theTopic, $theTableNr, $quiet ) = @_;

    $config->{TWiki}->{Func}->writeDebug ( "- EditTablePlugin::doSaveTable( $theWeb, $theTopic, $theTableNr, $quiet )" ) if $config->{TWiki}->{Plugins}->{EditTablePlugin}->{debug};

    my $text = $config->{TWiki}->{Func}->readTopicText ( $theWeb, $theTopic );

    my $cgiRows = $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}->param( 'etrows' ) || 1;
    my $tableNr = 0;
    my $rowNr = 0;
    my $insideTable = 0;
    my $doSave = 0;
    my $result = "";
    # appended stuff is a hack to handle EDITTABLE correctly if at end
    foreach( split( /\r?\n/, "$text\n<nop>\n" ) ) {
        if( /%EDITTABLE{(.*)}%/o ) {
            $tableNr += 1;
            if( $tableNr == $theTableNr ) {
               $doSave = 1;
            }
        }
        if( $doSave ) {
            if( /^(\s*)\|.*\|\s*$/ ) {
                $insideTable = 1;
                $rowNr++;
                if( $rowNr > $cgiRows ) {
                    # deleted row
                    $rowNr--;
                    next;
                }
                s/^(\s*)\|(.*)/$config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableRow ( $1, $2, $tableNr, $cgiRows, $rowNr, 1, 1 )/eo;

            } elsif( $insideTable ) {
                $insideTable = 0;
                if( $rowNr < $cgiRows ) {
                    while( $rowNr < $cgiRows ) {
                        $rowNr++;
                        $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableRow ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}, "", $tableNr, $cgiRows, $rowNr, 1, 1 ) . "\n";
                    }
                }
                $doSave = 0;
                $rowNr = 0;
            }
            if( /^\s*$/ ) {      # empty line
                if( $doSave ) {
                    # empty %EDITTABLE%, so create a default table
                    $rowNr = 0;
                    if( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{params}{"header"} ) {
                        $rowNr++;
                        $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableRow ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}, "", $tableNr, $cgiRows, $rowNr,1 , 1 ) . "\n";
                    }
                    while( $rowNr < $cgiRows ) {
                        $rowNr++;
                        $result .= $config->{TWiki}->{Plugins}->{EditTablePlugin}->handleTableRow ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{preSp}, "", $tableNr, $cgiRows, $rowNr, 1, 1 ) . "\n";
                    }
                }
                $doSave = 0;
                $rowNr = 0;
            }
        }
        $result .= "$_\n";
    }
    $result =~ s|\n<nop>\n$||o; # clean up hack that handles EDITTABLE correctly if at end

    my $error = $config->{TWiki}->{Func}->saveTopicText ( $theWeb, $theTopic, $result, "", $quiet );
    $config->{TWiki}->{Func}->setTopicEditLock ( $theWeb, $theTopic, 0 );  # unlock Topic
    my $url = $config->{TWiki}->{Func}->getViewUrl ( $theWeb, $theTopic );
    if( $error ) {
        $url = $config->{TWiki}->{Func}->getOopsUrl ( $theWeb, $theTopic, "oopssaveerr", $error );
    }
    $config->{TWiki}->{Func}->redirectCgiQuery ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}, $url );
}

# =========================
sub doCancelEdit
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my ( $theWeb, $theTopic ) = @_;

    $config->{TWiki}->{Func}->writeDebug ( "- EditTablePlugin::doCancelEdit( $theWeb, $theTopic )" ) if $config->{TWiki}->{Plugins}->{EditTablePlugin}->{debug};

    $config->{TWiki}->{Func}->setTopicEditLock ( $theWeb, $theTopic, 0 );

    $config->{TWiki}->{Func}->redirectCgiQuery ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}, $config->{TWiki}->{Func}->getViewUrl ( $theWeb, $theTopic ) );
}

# =========================
sub doEnableEdit
{ 
   my $self = shift;
	my $config = $self->{config} ;


    my ( $theWeb, $theTopic, $doCheckIfLocked ) = @_;

    $config->{TWiki}->{Func}->writeDebug ( "- EditTablePlugin::doEnableEdit( $theWeb, $theTopic )" ) if $config->{TWiki}->{Plugins}->{EditTablePlugin}->{debug};

    my $wikiUserName = $config->{TWiki}->{Func}->getWikiUserName ();
    if( ! $config->{TWiki}->{Func}->checkAccessPermission ( "change", $wikiUserName, "", $theTopic, $theWeb ) ) {
        # user has not permission to change the topic
        my $url = $config->{TWiki}->{Func}->getOopsUrl ( $theWeb, $theTopic, "oopsaccesschange" );
        $config->{TWiki}->{Func}->redirectCgiQuery ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}, $url );
        return 0;
    }

    my( $oopsUrl, $lockUser ) = $config->{TWiki}->{Func}->checkTopicEditLock ( $theWeb, $theTopic );
    if( ( $doCheckIfLocked ) && ( $lockUser ) ) {
        # warn user that other person is editing this topic
        $config->{TWiki}->{Func}->redirectCgiQuery ( $config->{TWiki}->{Plugins}->{EditTablePlugin}->{query}, $oopsUrl );
        return 0;
    }
    $config->{TWiki}->{Func}->setTopicEditLock ( $theWeb, $theTopic, 1 );

    return 1;
}

# =========================

# The following code is copied from the ChartPlugin Table object.


use TWiki::Plugins::Table ; 

1;
