
package HTML::WebMake::CGI::EditFile;

use strict;
use HTML::WebMake::CGI::Edit;
use File::Basename;

use vars	qw{
  	@ISA $ERRORS_TMPL $OK_TMPL
        $PAGE_TITLE $PAGE_HEADER
};

@ISA = qw(HTML::WebMake::CGI::Edit);

###########################################################################

$PAGE_TITLE = q{ Edit File "__FNAME__" };
$PAGE_HEADER = q{ Edit File };

$ERRORS_TMPL = q{ <p>

    Some errors were encountered.  Either go back and re-edit to fix them,
    or abandon the changes that could not be committed and return to <a
    href="__REINVOKE__dir={dirurl}__">the directory listing</a>.

</p> };

$OK_TMPL = q{ <p>

    Your changes have been submitted.  Thanks!  Now return to <a
    href="__REINVOKE__dir={dirurl}__">the directory listing</a>.

</p> }; #"

###########################################################################

sub new {
  my $class = shift;
  $class = ref($class) || $class;
  my $self = $class->SUPER::new (@_);

  $self->{page_title} = $PAGE_TITLE;
  $self->{page_header} = $PAGE_HEADER;

  bless ($self, $class);
  $self;
}

###########################################################################

sub subrun {
  my ($self, $q) = @_;
  my $form;

  my $dirurl = $self->mydirurl();
  my $base = basename ($self->{filename});
  $self->{task_breadcrumb} = qq{
    <a href="__REINVOKE__dir=${dirurl}__">$dirurl/</a>
    &raquo;
    $base
  };#"

  if ($q->param ('dump')) {
    $form = $self->write_dump_page ();
  } elsif ($q->param ('Save')) {
    $form = $self->write_save_page ();
  # } elsif ($q->param ('Preview')) {
    # $form = $self->write_preview_page ();
  } else {
    $form = $self->write_edit_page ();
  }

  $form;
}

sub write_edit_page
{
  my $self = shift;
  my $q = $self->{q};

  my $allmetas = $self->{metatable}->read_metatable_file ($self->{file_base});
  if (defined $allmetas) {
    $self->{read_metas} = $allmetas->{$self->{filename}};
  }

  return $self->base_edit_form ($q);
}

# ---------------------------------------------------------------------------

sub cgi_hidden_items {
  my ($self, $q) = @_;

  return $q->hidden(-name=>'edit',-value=>'1')
      . $q->hidden(-name=>'f', -value=>$self->{filename});
}

# ---------------------------------------------------------------------------

sub get_item_text {
  my ($self, $q) = @_;

  my $text = '';
  if (open (IN, "<".$self->{file_base}."/".$self->{filename})) {
    if ($self->is_media($self->{filename})) {
      binmode IN;
    }
    $text = join ('', <IN>); close IN;

  } else {
    # no such file.  See if we have an 'addtemplate' attribute...
    $text = $self->get_addtemplate_text ($self->{file_base}, $self->{filename});
  }

  if (!$self->is_media($self->{filename})) {
    $text =~ s/\r//gs;
    # strip metadata from the text
    return $self->strip_wmmetas ($text);

  } else {
    return $text;
  }
}

# ---------------------------------------------------------------------------

sub get_addtemplate_text {
  my ($self, $filebase, $filename) = @_;

  my $dir = $filename;
  while ($dir =~ s/([\/\\\:])[^\/\\\:]*$//g) {
    $filename = $filebase.$1.$dir.$1."NEW_FILE_TEMPLATE";
    if (-r $filename) {
      if (open (IN, "<".$filename)) {
	my $text = join ('', <IN>); close IN;
	$filename =~ s/\Q$filebase\E/(Top)/gs;
	$self->info ("This is a new item: using \"<b>$filename</b>\".");
	return $text;
      }
    }
  }

  return '';
}

# ---------------------------------------------------------------------------

sub write_save_page
{
  local ($_);
  my $self = shift;
  my $q = $self->{q};
  my $form = '';

  if ($self->is_media($self->{filename}))
  {
    return unless $self->update_metatable ();
  } else {
    return unless $self->create_wmmetas ();
  }

  my $textfrom = $q->param ('text_from');
  my $filename;

  my $url = $q->param ('upload_url');
  if ($textfrom eq 'Load from URL' && $url !~ /\S/) {
    # no URL entered: do not change the file
    goto skipfilemod;
  }

  if (!open (FILE, ">".$self->{file_base}."/".$self->{filename})) {
    $self->warn ("cannot write to {WMROOT}/".$self->{filename}."!");
    goto failed;
  }

  $_ = undef;
  if ($q->param('upload')) {
    my $infile = $q->upload ("upload_file");
    if (!defined $infile) {
      $self->warn ("Incomplete upload, didn't receive the new text!");
      goto failed;
    }

    if ($self->is_media($self->{filename})) {
      binmode FILE;
      my $bytesread;
      while ($bytesread=read($infile,$_,1024)) { print FILE $_; }

    } else {
      $_ = join ('', <$infile>);
    }

  } elsif ($textfrom eq 'Load from URL') {
    my $url = $q->param ('upload_url');
    $self->warn ("TODO: load from url");

  } else {
    $_ = $q->param ('upload_text');
  }

  if (!$self->is_media ($self->{filename})) {
    s/\r//gs;			# clean MS-DOSisms
    print FILE $self->{wmmetas}.$_;

    if (!close FILE) {
      $self->warn ("cannot write to {WMROOT}/".$self->{filename}."!");
      goto failed;
    }

    if ($self->{cvs_supported} && !$self->{cvs}->file_in_cvs ($self->{filename}))
    {
      $self->cvs_add ($self->{filename});
      $form .= qq{
	<p>
	(Added "$self->{filename}" to the list of files to be added
	at the next CVS commit.)
	</p>
      };#"
    }
  }

skipfilemod:
  # TODO -- handle link_text
  ;

failed:
  my $dirurl = $self->mydirurl();

  if ($self->{msgs} ne '') {
    return $form.$self->subst_template ($ERRORS_TMPL, { dirurl => $dirurl });
  } else {
    return $form.$self->subst_template ($OK_TMPL, { dirurl => $dirurl });
  }

  $form;
}

# ---------------------------------------------------------------------------

sub update_metatable {
  my ($self) = @_;
  my $q = $self->{q};
  if (!$self->{metatable}->lock_metatable_file ($self->{file_base})) {
    $self->warn ("failed to lock metadata table: ".
    	"someone else may be updating content here, in which case try again ".
	"later -- or you may not have write permissions to the filesystem.");
    return 0;		# TODO
  }

  my $res = $self->rewrite_metatable ($q);
  $self->{metatable}->unlock_metatable_file ($self->{file_base});

  if (!$res) {
    $self->warn ("write/unlink/rename of metadata table failed!");
    return 0;
  }
  1;
}

# ---------------------------------------------------------------------------

sub rewrite_metatable {
  my ($self, $q) = @_;

  my $tbl = $self->{metatable}->read_metatable_file ($self->{file_base});

  my $fname = $self->{filename};
  if (!defined $tbl->{$fname}) { $tbl->{$fname} = { }; }

  foreach my $name ($q->param()) {
    next unless ($name =~ /^m_(\S+)/);
    my $metaname = $1; $metaname =~ s/\"/_/gs;

    my $val = $q->param ($name);
    next if ($val =~ /^\s*$/);
    $val =~ s/<(\/\s*meta\s*>)/\&lt;$1/gs; # escape end-of-metadata tags

    $tbl->{$fname}->{$metaname} = $val;
  }

  $self->{metatable}->rewrite_metatable_file ($self->{file_base});
}

###########################################################################

1;
