#!/usr/bin/perl

# Helper script for context help in Cinelerra
# Calling: ContextManual.pl "<help keyphrase>"
# Searches the requested key in the following order:
# 1) manual Contents
# 2) manual Index
# 3) all manual pages via grep
# 4) FFmpeg or Ladspa plugins
# The first item found is shown via the default web browser
# If nothing found, the Contents itself is shown
# On empty keyphrase do nothing
# The special keyphrase "TOC" shows Contents, "IDX" shows Index
# The keyphrase starting with "FILE:" shows the file named after colon
# The special keyphrase "API" shows the numeric version of the script itself

# Several important definitions

# ContextManual.pl script API version. Must not be changed !
$cin_cm_api = 3;

# Web browser executable, can be redefined on user's demand
$cin_browser = $ENV{'CIN_BROWSER'};
# a likely default browser
$cin_browser = 'firefox' if $cin_browser eq '';
# another possible browser
#$cin_browser = 'xdg-open' if $cin_browser eq '';
# a fake browser for debugging
#$cin_browser = 'echo';

# The following definitions depend on the HTML manual structure
# There is nothing to change below this line

# The node with the manual contents
$contents_node = 'Contents.html';

# The node with the actual index if needed will be found after parsing contents
$index_node = '';
$index = '';

# Several special plugin names necessary to rewrite
%rewrite = (
  # Rendered effects and transitions are not segmented in the Contents
  "CD Ripper"           => "Rendered Audio Effects",
  "Normalize"           => "Rendered Audio Effects",
  "Resample"            => "Rendered Audio Effects",
  "Time stretch"        => "Rendered Audio Effects",

  "720 to 480"          => "Rendered Video Effects",
  "Reframe"             => "Rendered Video Effects",

  # Audio transitions are segmented in the Index
#  "Crossfade"           => "Audio Transitions",

  # Video transitions are segmented in the Index
#  "BandSlide"           => "Video Transitions",
#  "BandWipe"            => "Video Transitions",
#  "Dissolve"            => "Video Transitions",
#  "Flash"               => "Video Transitions",
#  "IrisSquare"          => "Video Transitions",
#  "Shape Wipe"          => "Video Transitions",
#  "Slide"               => "Video Transitions",
#  "Wipe"                => "Video Transitions",
#  "Zoom"                => "Video Transitions",

  # Several not properly matched names
  "AgingTV"             => "Aging TV",
  "Brightness/Contrast" => "Brightness\\/Contrast",
  "Chroma key (HSV)"    => "Chroma Key \\(HSV\\)",
  "Chroma key (Avid)"   => "Chroma Key \\(Avid\\)",
  "Crop & Position"     => "Crop &amp; Position",
  "FindObj"             => "Find Object",
  "RGB - 601"           => "RGB-601",
  "ShiftInterlace"      => "Shift Interlace",
  "Cinelerra: Scopes"   => "Videoscope"
  );

# Cinelerra installation path
$cin_dat = $ENV{'CIN_DAT'};
$cin_dat = '.' if $cin_dat eq '';

# Cinelerra HTML manual must reside here
$cin_man = "$cin_dat/doc/CinelerraGG_Manual";
$contents = $cin_man.'/'.$contents_node;
#print "ContextManual: using contents $contents\n";

# Cinelerra user's config directory
$cin_config = $ENV{'CIN_CONFIG'};
$cin_config = $ENV{'HOME'}.'/.bcast5'
  if $cin_config eq '' && $ENV{'HOME'} ne '';
$cin_config = '.' if $cin_config eq '';
$me_config = "$cin_config/ContextManual.pl";
#print "ContextManual: user script=$me_config\n";

# 1st argument is the requested key
$help_key = $ARGV[0];
#print "ContextManual: request=$help_key\n";
# Do nothing if no key requested
exit 0 if $help_key eq '';

# A special internal request: output own API version
if ($help_key eq 'API')
{
  print "$cin_cm_api\n";
  exit 0;
}

# If a system (not user's) script instance is executed, and the API versions
# of both scripts do not match, then copy the system script to the user's one
# (making a backup copy of the latter). Then execute it with the same key.
if ($0 ne $me_config)
{
  $me_api = 0;
  $me_api = `\"$me_config\" API` if -x $me_config;
  if ($me_api != $cin_cm_api)
  {
    print "ContextManual: copying \"$0\" to \"$me_config\"\n";
    unlink "$me_config.bak" if -f "$me_config.bak";
    rename "$me_config", "$me_config.bak" if -f $me_config;
    system "cp \"$0\" \"$me_config\"";
    system "chmod +x \"$me_config\"";
  }
  exec "\"$me_config\" \"$help_key\"" if -x $me_config;
}

# If a user's script instance is executed, do everything by myself
#print "ContextManual: executing \"$0\" \"$help_key\"\n";

# Show contents on this special request
if ($help_key eq 'TOC')
{
  system "$cin_browser \"file://$contents\" &";
  exit 0;
}
# Show index on this special request
if ($help_key eq 'IDX')
{
  # Index node will be needed now, find it
  if ($index_node eq '')
  {
    $node = '';
    open CONTENTS, $contents or die "Cannot open $contents: $!";
    while (<CONTENTS>)
    {
      chomp;
      last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*Index\s*<\/A>(?:<\/B>)?$/;
    }
    close CONTENTS;
    $index_node = $node if $node ne '';
    $index_node = 'Index.html' if $index_node eq '';
    $index = $cin_man.'/'.$index_node;
  }
  system "$cin_browser \"file://$index\" &";
  exit 0;
}
# Show the named file on this special request
if ($help_key =~ /^FILE:/)
{
  $help_key =~ s/^FILE://;
  $help_key = $cin_man.'/'.$help_key;
  system "$cin_browser \"file://$help_key\" &";
  exit 0;
}

$help_key = $rewrite{$help_key} if exists $rewrite{$help_key};
# Do nothing if no key requested
exit 0 if $help_key eq '';
# Show contents on this special request
if ($help_key eq 'TOC')
{
  system "$cin_browser \"file://$contents\" &";
  exit 0;
}
# Show index on this special request
if ($help_key eq 'IDX')
{
  # Index node will be needed now, find it
  if ($index_node eq '')
  {
    $node = '';
    open CONTENTS, $contents or die "Cannot open $contents: $!";
    while (<CONTENTS>)
    {
      chomp;
      last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*Index\s*<\/A>(?:<\/B>)?$/;
    }
    close CONTENTS;
    $index_node = $node if $node ne '';
    $index_node = 'Index.html' if $index_node eq '';
    $index = $cin_man.'/'.$index_node;
  }
  system "$cin_browser \"file://$index\" &";
  exit 0;
}
# Show the named file on this special request
if ($help_key =~ /^FILE:/)
{
  $help_key =~ s/^FILE://;
  $help_key = $cin_man.'/'.$help_key;
  system "$cin_browser \"file://$help_key\" &";
  exit 0;
}

# Now try searching...
open CONTENTS, $contents or die "Cannot open $contents: $!";
$node = '';
# First search contents for the exact key
while (<CONTENTS>)
{
  chomp;
  last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*$help_key\s*<\/A>$/;
}
# If not found, search contents for an approximate key
if ($node eq '')
{
  seek CONTENTS, 0, 0;
  while (<CONTENTS>)
  {
    chomp;
    last if ($node) = /^\s*HREF=\"(.+?\.html)\">.*?$help_key.*?<\/A>$/i;
  }
}

# Index node will be needed now, find it
if ($node eq '' && $index_node eq '')
{
  seek CONTENTS, 0, 0;
  while (<CONTENTS>)
  {
    chomp;
    last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*Index\s*<\/A>(?:<\/B>)?$/;
  }
  $index_node = $node if $node ne '';
  $index_node = 'Index.html' if $index_node eq '';
  $index = $cin_man.'/'.$index_node;
  $node = '';
}

# If not found, search index for the exact key
if ($node eq '')
{
  open INDEX, $index or die "Cannot open $index: $!";
  while (<INDEX>)
  {
    chomp;
    # Cut off anchor: xdg-open does not like it
    last if ($node) = /<A\s+HREF=\"(.+?\.html)(?:#\d+)?\">\s*$help_key\s*<\/A>$/;
    # Retain anchor
#    last if ($node) = /<A\s+HREF=\"(.+?\.html(?:#\d+)?)\">\s*$help_key\s*<\/A>$/;
  }
  close INDEX;
}
# If not found, search index for an approximate key
if ($node eq '')
{
  open INDEX, $index or die "Cannot open $index: $!";
  while (<INDEX>)
  {
    chomp;
    # Cut off anchor: xdg-open does not like it
    last if ($node) = /<A\s+HREF=\"(.+?\.html)(?:#\d+)?\">.*?$help_key.*?<\/A>$/i;
    # Retain anchor
#    last if ($node) = /<A\s+HREF=\"(.+?\.html(?:#\d+)?)\">.*?$help_key.*?<\/A>$/i;
  }
  close INDEX;
}

# If not found, grep manual for exact key instance
if ($node eq '')
{
  $_ = `grep -l \"$help_key\" \"$cin_dat\"/doc/CinelerraGG_Manual/*.html`;
  ($node) = split;
}
# If not found, grep manual for case insensitive key instance
if ($node eq '')
{
  $_ = `grep -il \"$help_key\" \"$cin_dat\"/doc/CinelerraGG_Manual/*.html`;
  ($node) = split;
}

if ($node eq '')
{
  if ($help_key =~ /^F_/)
  { # If not found, search contents for FFmpeg plugins
    $help_key = 'FFmpeg Audio and Video Plugins';
    seek CONTENTS, 0, 0;
    while (<CONTENTS>)
    {
      chomp;
      last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*$help_key\s*<\/A>$/;
    }
  }
  elsif ($help_key =~ /^L_/)
  { # If not found, search contents for LADSPA plugins
    $help_key = 'Audio Ladspa Effects';
    seek CONTENTS, 0, 0;
    while (<CONTENTS>)
    {
      chomp;
      last if ($node) = /^\s*HREF=\"(.+?\.html)\">\s*$help_key\s*<\/A>$/;
    }
  }
}

close CONTENTS;

# If still nothing found, show contents
$node = $contents_node if $node eq '';
$node = $cin_man.'/'.$node unless $node =~ /\//;
#print "ContextManual: found $node\n";

# Call browser to show the proposed HTML file
system "$cin_browser \"file://$node\" &";

# And immediately return to the caller
exit 0;
