package App::Followme::Initialize;
use 5.008005;
use strict;
use warnings;
use lib '../..';

use Cwd;
use IO::File;
use MIME::Base64  qw(decode_base64);
use File::Spec::Functions qw(splitdir catfile);

use App::Followme::FIO;
use App::Followme::NestedText;

our $VERSION = "1.97";

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(initialize);

our $var = {};
use constant CMD_PREFIX => '#>>>';

#----------------------------------------------------------------------
# Initialize a new web site

sub initialize {
    my ($directory) = @_;

    chdir($directory) if defined $directory;
    my ($read, $unread) = data_readers();

    while (my ($command, $lines) = next_command($read, $unread)) {
        my @args = split(' ', $command);
        my $cmd = shift @args;

        write_error("Missing lines after command", $command)
            if $cmd eq 'copy' && @$lines == 0;

        write_error("Unexpected lines after command", $command)
            if $cmd ne 'copy' && @$lines > 0;

        if ($cmd  eq 'copy') {
            write_file($lines, @args);

        } else {
            write_error("Error in command name", $command);
        }
    }

    return;
}

#----------------------------------------------------------------------
# Copy a binary file

sub copy_binary {
    my($file, $lines, @args) = @_;
    return if -e $file;

    my $out = IO::File->new($file, 'w') or die "Couldn't write $file: $!\n";
    binmode($out);

    foreach my $line (@$lines) {
        print $out decode_base64($line);
    }

    close($out);
    return;
}

#----------------------------------------------------------------------
# Copy a configuration file

sub copy_configuration {
    my ($file, $lines, @args) = @_;
    
    my $config;
    my %old_config = nt_parse_almost_yaml_string(join('', @$lines));

    if (-e $file) {
        my $page = fio_read_page($file);

        if ($page =~ /:[ \n]/) {
            my %new_config = nt_parse_almost_yaml_string($page);
            $config = nt_merge_items(\%old_config, \%new_config);

        } else {
            my $new_file = $file;
            $new_file =~ s/\.*$/ocfg/;
            rename($file, $new_file);
            $config = \%old_config;
        }

    } else {
        $config = \%old_config;
    }

    nt_write_almost_yaml_file($file, %$config);
    return;
}

#----------------------------------------------------------------------
# Copy a text file

sub copy_text {
    my ($file, $lines, @args) = @_;
    return if -e $file;

    my $out = IO::File->new($file, 'w') or die "Couldn't write $file: $!\n";
    foreach my $line (@$lines) {
        print $out $line;
    }

    close($out);
    return;
}

#----------------------------------------------------------------------
# Check path and create directories as necessary

sub create_dirs {
    my ($file) = @_;

    my @dirs = splitdir($file);
    pop @dirs;

    my @path;
    while (@dirs) {
        push(@path, shift(@dirs));
        my $path = catfile(@path);

        if (! -d $path) {
            mkdir($path) or die "Couldn't create $path: $!\n";
            chmod(0755, $path) or die "Couldn't set permissions: $!\n";
        }
    }

    return;
}

#----------------------------------------------------------------------
# Return closures to read the data section of this file

sub data_readers {
    my @pushback;

    my $read = sub {
        if (@pushback) {
            return pop(@pushback);
        } else {
            return <DATA>;
        }
    };

    my $unread = sub {
        my ($line) = @_;
        push(@pushback, $line);
    };

    return ($read, $unread);
}

#----------------------------------------------------------------------
# Is the line a command?

sub is_command {
    my ($line) = @_;

    my $command;
    my $prefix = CMD_PREFIX;

    if ($line =~ s/^$prefix//) {
        $command = $line;
        chomp $command;
    }

    return $command;
}

#----------------------------------------------------------------------
# Get the name and contents of the next file

sub next_command {
    my ($read, $unread) = @_;

    my $line = $read->();
    return unless defined $line;

    my $command = is_command($line);
    die "Command not supported: $line" unless $command;

    my @lines;
    while ($line = $read->()) {
        if (is_command($line)) {
            $unread->($line);
            last;

        } else {
            push(@lines, $line);
        }
    }

    return ($command, \@lines);
}

#----------------------------------------------------------------------
# Die with error

sub write_error {
    my ($msg, $line) = @_;
    die "$msg: " . substr($line, 0, 30) . "\n";
}

#----------------------------------------------------------------------
# Write a copy of the input file

sub write_file {
    my ($lines, @args) = @_;

    no strict;
    my $type = shift(@args);
    my $file = shift(@args);

    create_dirs($file);

    my $sub = "copy_$type";
    &$sub($file, $lines, @args);

    return;
}

1;
__DATA__
#>>> copy binary banner.jpg

AAAEAH//2Q==
#>>> copy text followme.cfg
run_before:
    - App::Followme::FormatPage
    - App::Followme::ConvertPage
#>>> copy text index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<!-- section meta -->
<title>Your Site</title>
<!-- endsection meta -->
<link rel="stylesheet" id="css_style" href="theme.css">
</head>
<body>
<header>
<div><img src="banner.jpg"></div>
<span class= "title"><a href="#">Your Title Here</a></span>
<div class="dropdown" style="float:right;">
    <button class="dropbtn">&#9776;</button>
    <nav class="dropdown-content">
      <a href="essays/index.html">Essays</a>
      <a href="photos/index.html">Photos</a>
      <a href="help/index.html">Help</a>
    </nav>
</div>
</header>
<article>
<section id="primary">
<!-- section primary -->
<h2>Followme</h2>

<p>Usage: followme [file or directory]</p>

<p>Update a static website after changes. Constant portions of each page are
updated to match, text files are converted to html, and indexes are created
for new files in the archive.</p>

<p>The script is run on the directory or file passed as its argument. If no
argument is given, it is run on the current directory.</p>

<p>If a file is passed, the script is run on the directory the file is in. In
addition, the script is run in quick mode, meaning that only the directory
the file is in is checked for changes. Otherwise not only that directory, but
all directories below it are checked.</p>

<p>Followme can be downloaded from CPAN as App::Followme.</p>

<p>This file is used as a template for the site. Any markup outside the section 
comments will be shared between all pages. Modify it to get the desired look for 
your site. The subdirectories show some of the capabilities of this application.
Keep or modify them as you wish.</p>

<p>See <a href="help/index.html">help</a> for more information about this 
script.</p>

<!-- endsection primary-->
<section id="secondary">
<!-- section secondary -->
<!-- endsection secondary-->
</section>
</article>
<footer>
    <nav class="footer-content">
        <a href="essays/index.html">Essays</a>
        <a href="photos/index.html">Photos</a>
        <a href="help/index.html">Help</a>
    </nav>
</footer>
</body>
</html>
#>>> copy text theme.css
/*
    Global styles
*****************/
body {
    font-family: helvetica, arial, sans-serif;
    line-height: 1.5;
    margin: 0 auto;
    max-width: 50em;
    padding: 0 1em;
}
h1, h2, h3, h4, h5, h6 {
    margin: 1em 0 0.5em 0;
    line-height: 1.2em;
}
img {
    max-width: 100%;
}
figure {
    margin: 1em 0;
    text-align: center;
}
figcaption {
    font-size: small;
}
pre, code, samp, kbd {
    color: #009;
    font-family: monospace, monospace;
    font-size: 0.9em;
}
pre code, pre samp, pre kbd {
    font-size: 1em;
}
pre kbd {
    color: #060;
}
pre {
    background: #eee;
    padding: 0.5em;
    overflow: auto;
}
blockquote {
    background: #eee;
    border-left: medium solid #ccc;
    margin: 1em 0;
    padding: 0.5em;
}
blockquote :first-child {
    margin-top: 0;
}
blockquote :last-child {
    margin-bottom: 0;
}  
/*
    Header
*****************/
header {
    padding: 0; 
    background: #222;
    border-radius: 6px;
}
.title {
    padding: 16px;
    font-size: 1.75em;
}
.title a {
    text-decoration: none;
    color: #aaa; 
}
.title a:hover {
      color: #fff;
}
/*
    Footer
*****************/
footer {
    padding: 8px; 
    background: #222;
    border-radius: 6px;
}
.footer-content a {
    padding: 16px;
    text-decoration: none;
    color: #aaa; 
}
.footer-content a:hover {
    color: #fff;
}
/*
    Menu
*****************/
.dropbtn {
    font-size: 1.75em;
    background-color: #222;
    color: #aaa;
    border: none;   
    cursor: pointer;
}  
.dropdown {
    position: relative;
    display: inline-block;
} 
.dropdown-content {
    display: none;
    position: absolute;
    right: 0;
    background-color: #222;
    min-width: 160px;
    border-radius: 6px;
    z-index: 1;
} 
.dropdown-content a {
    color: #aaa;
    padding: 12px 16px;
    border-radius: 6px;
    text-decoration: none;
    display: block;
} 
.dropdown-content a:hover {
    color: #fff;
}
.dropdown:hover .dropdown-content {
    display: block;
}
.dropdown:hover .dropbtn {
    color:#fff;
    background-color: #222;
    border-color: #222;
}
/*
    Photo Gallery
*****************/
#gallery { 
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    grid-gap: 10px;
    align-items: start;
    }
  
  .thumb {
      border: 1px solid #ccc;
      box-shadow: 2px 2px 6px 0px  rgba(0,0,0,0.3);
      max-width: 100%;
  }
  
  .lightbox {
      position: fixed;
      z-index: 999;
      height: 0;
      width: 0;
      text-align: center;
      top: 0;
      left: 0;
      background: rgba(0, 0, 0, 0.8);
      opacity: 0;
  }
  
  .lightbox img {
      max-width: 90%;
      max-height: 80%;
      margin-top: 2%;
      opacity: 0;
  }
  
  .lightbox:target {
      /** Remove default browser outline */
      outline: none;
      width: 100%;
      height: 100%;
      opacity: 1 !important;
      
  }
  
  .lightbox:target img {
      border: solid 17px rgba(77, 77, 77, 0.8);
      opacity: 1;
      webkit-transition: opacity 0.6s;
      transition: opacity 0.6s;
  }
  
  .light-btn {
      color: #fafafa;
      background-color: #333;
      border: solid 3px #777;
      padding: 5px 15px;
      border-radius: 1px;
      text-decoration: none;
      cursor: pointer;
      vertical-align: middle;
      position: absolute;
      top: 45%;
      z-index: 99;
  }
  
  .light-btn:hover {
      background-color: #111;
  }
  
  .btn-prev {
      left: 7%;
  }
  
  .btn-next {
      right: 7%;
  }
  
  .btn-close {
      position: absolute;
      right: 2%;
      top: 2%;
      color: #fafafa;
      background-color: #92001d;
      border: solid 5px #ef4036;
      padding: 10px 15px;
      border-radius: 1px;
      text-decoration: none;
  }
  
  .btn-close:hover {
      background-color: #740404;
  }
#>>> copy text _templates/convert_page.htm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- section meta -->
<base href="$site_url/" />
<title>$title</title>
<meta name="date" content="$mdate" />
<meta name="description" content="$description" />
<meta name="keywords" content="$keywords" />
<meta name="author" content="$author" />
<!-- endsection meta -->
</head>
<body>
<header>
<h1>Site Title</h1>
</header>
<article>
<section id="primary">
<!-- section primary -->
<h2>$title</h2>
$body
<!-- endsection primary-->
</section>
<section id="secondary">
<!-- section secondary -->
<!-- endsection secondary-->
</section>
</article>
</body>
</html>
#>>> copy text _templates/create_gallery.htm
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- section meta -->
<base href="$site_url/" />
<title>$title</title>
<meta name="date" content="$mdate" />
<meta name="description" content="$description" />
<meta name="keywords" content="$keywords" />
<meta name="author" content="$author" />
<!-- endsection meta -->
<link rel="stylesheet" id="css_style" href="theme.css">
</head>
<body>
<header>
<h1>Site Title</h1>
</header>
<article>
<section id="primary">
<!-- section primary -->
<!-- endsection primary-->
</section>
<section id="secondary">
<!-- section secondary -->
<section id="gallery">
<!-- for @files -->
<a href="$index_url#$target">
<!-- for @thumb_file -->
<img class="thumb" src="$url">
<!-- endfor -->
</a>
<div class="lightbox" id="$target">
<a href="$index_url#$target_previous" class="light-btn btn-prev">prev</a>
<a href="$index_url#_" class="btn-close">X</a>
<img src="$url">
<a href="$index_url#$target_next" class="light-btn btn-next">next</a>
</div>
<!-- endfor -->
</section>
<!-- endsection secondary-->
</section>
</article>
</body>
</html>
#>>> copy text _templates/create_help.htm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- section meta -->
<base href="$site_url/" />
<title>$title</title>
<meta name="date" content="$mdate" />
<meta name="description" content="$description" />
<meta name="keywords" content="$keywords" />
<meta name="author" content="$author" />
<!-- endsection meta -->
</head>
<body>
<header>
<h1>Site Title</h1>
</header>
<article>
<section id="primary">
</section>
<section id="secondary">
<!-- section secondary -->
<!-- for @all_files -->
<h2>$title</h2>

$body
<!-- endfor -->

<!-- endsection secondary-->
</section>
</article>
</body>
</html>
#>>> copy text _templates/create_index.htm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- section meta -->
<base href="$site_url/" />
<title>$title</title>
<meta name="date" content="$mdate" />
<meta name="description" content="$description" />
<meta name="keywords" content="$keywords" />
<meta name="author" content="$author" />
<!-- endsection meta -->
</head>
<body>
<header>
<h1>Site Title</h1>
</header>
<article>
<section id="primary">
</section>
<section id="secondary">
<!-- section secondary -->
<h2>$title</h2>

<ul>
<!-- for @files_by_title -->
<li><a href="$url">$title</a></li>
<!-- endfor -->
</ul>
<!-- endsection secondary-->
</section>
</article>
</body>
</html>
#>>> copy text _templates/create_news.htm
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- section meta -->
<base href="$site_url/" />
<title>$title</title>
<meta name="date" content="$mdate" />
<meta name="description" content="$description" />
<meta name="keywords" content="$keywords" />
<meta name="author" content="$author" />
<!-- endsection meta -->
</head>
<body>
<header>
<h1>Site Title</h1>
</header>
<article>
<section id="primary">
</section>
<section id="secondary">
<!-- section secondary -->
<!-- for @top_files_by_mdate_reversed -->
<p>$summary</p>
<p><a href="$url">More ...</a></p>

<!-- endfor -->
<h3>Archive</h3>
<p>Other essays can be found in the following sections:</p>
<p>
<!-- for @folders -->
<a href="$url">$title</a>&nbsp;&nbsp;
<!-- endfor -->
</p>
<!-- endsection secondary-->
</section>
</article>
</body>
</html>
#>>> copy text essays/followme.cfg
run_before:
    - App::Followme::CreateIndex
template_file: create_news.htm
#>>> copy text essays/index.md
----
title: Essays Directory
description: A collection of short essays on various topics
keywords: essays
----
This folder is configured (via followme.cfg) to contain short essays 
on various topics. To use it, create subdirectories for each topic.
write your essay in Markdown format, and save the file in the appropriate
subdirectory. You can also include metadata for the essay, such as the 
title at the top of the file, just as has been done in this file. 

When followme is run, it will create an index for files in the current directory 
and its subdirectories that contain the text of the most recently modified files 
together with links to the files. It can also be used to create a basic weblog.
#>>> copy text essays/archive/followme.cfg
run_before:
    - App::Followme::CreateIndex
template_file: create_index.htm
#>>> copy text essays/archive/index.md
----
title: Archive Directory
description: Archive of short essays
keywords: essays, archive
----
This folder is configured (via followme.cfg) to contain an archive of
previously written essays. When followme is run, it will create an index 
for files in the current directory  containing a link to each essay in the 
archive.
#>>> copy text help/followme.cfg
run_before:
    - App::Followme::ConvertPage
    - App::Followme::CreateIndex
package: App::Followme
data_pkg: App::Followme::PodData
CreateIndex::template_file: create_help.htm
ConvertPage::extension: pm
CreateIndex::extension: pod
#>>> copy text help/index.md
----
title: Help Directory
description: Help files for followme
keywords: help
----
This folder contains an html version of the main help file for
followme.
#>>> copy text photos/followme.cfg
run_before:
    - App::Followme::CreateGallery
target_prefix: img
#>>> copy text photos/index.md
----
title: Photo Gallery
description: A collection of photos of interest
----
This folder is configured (via followme.cfg) to contain a photo 
gallery. If you add or subtract photos from this folder and run
followme, it will update the gallery. Each photo must have a 
thumbnail whose name is related to the photo like this:
photo-thumb.jpg. The suffix (-thumb) can be set in the configuration
file.
