#!/usr/bin/perl
# This code was forked from the LiveJournal project owned and operated
# by Live Journal, Inc. The code has been modified and expanded by
# Dreamwidth Studios, LLC. These files were originally licensed under
# the terms of the license supplied by Live Journal, Inc, which can
# currently be found at:
#
# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt
#
# In accordance with the original license, this code and all its
# modifications are provided under the GNU General Public License.
# A copy of that license can be found in the LICENSE file included as
# part of this distribution.
# ----------------------------------------------------------------------------
#   S2 editor library generation script                           08/03/2005
#
#   Generates s2library.js from the core layer definitions.
# ----------------------------------------------------------------------------

use strict;
use warnings;
use Getopt::Long;
use Pod::Usage;

my ( $filename, $layerid, $query, $outputpath, $help );
GetOptions(
    'help|h'       => \$help,
    'filename|f=s' => \$filename,
    'layerid|l=i'  => \$layerid,
    'query|q'      => \$query,
    'output|o=s'   => \$outputpath
) or pod2usage(1);
pod2usage(0) if $help;

my $home = $ENV{LJHOME} or die "You'll have to set \$LJHOME first.\n";
require "$home/cgi-bin/ljlib.pl";
require "$home/cgi-bin/LJ/S2.pm";

$outputpath ||= "$home/htdocs/js/s2edit/s2library.js";

my $info;
if ($filename) {
    local $/ = undef;
    open F, $filename or die $!;
    eval <F>;
    die $@ if $@;
    close F;

    $info = S2::get_layer_all( defined($layerid) ? $layerid : 1 );
}
elsif ($query) {
    my $pub = LJ::S2::get_public_layers();
    my $id  = $pub->{core1};
    $id = $id ? $id->{'s2lid'} : 0;
    die "Couldn't locate a core 1 layer.\n" unless $id;

    my $dbr = LJ::get_db_reader();
    my $rv  = S2::load_layers_from_db( $dbr, $id );
    $info = S2::get_layer_all($id);
}
else {
    pod2usage(1);
}

open LIB, ">$outputpath" or die "Failed to open $outputpath for writing: $!\n";
select LIB;
print "// Automatically generated by gens2editlib.pl\n";
print "// Do not edit!\n\n";

# ----------------------------------------------------------------------------
#   Classes
# ----------------------------------------------------------------------------

print "// Classes\n";
print "var s2classlib = new Array(";

my %classes = %{ $info->{'class'} };
my @orderedClasses =
    map { $_->[0] } sort { $a->[1] cmp $b->[1] } map { [ $_, lc $_ ] } keys %classes;

my $cma = 0;

foreach my $className (@orderedClasses) {
    my $class = $classes{$className};

    my ( %methods, %members );
    my $c = $class;
    do {
        %methods = ( %methods, %{ $c->{funcs} } );
        %members = ( %members, %{ $c->{vars} } );

        $c = ( $c->{'parent'} ? $classes{ $c->{'parent'} } : undef );
    } while ($c);

    print "," if $cma++;

    print "\n\t{\n\t\tname: '$className',\n";

    print "\t\tmembers: new Array(";
    my $cm = 0;
    foreach my $memberName ( sort keys %members ) {
        print "," if $cm++;

        print "\n\t\t\t{ ";
        print "name: '$memberName', ";
        print "type: '$members{$memberName}->{type}'";
        print " }";
    }
    print "),\n";

    print "\t\tmethods: new Array(";
    $cm = 0;
    foreach my $methodName ( sort keys %methods ) {
        print "," if $cm++;

        print "\n\t\t\t{ ";
        print "name: '$methodName', ";
        print "type: '$methods{$methodName}->{returntype}'";
        print " }";
    }
    print ")\n";

    print "\t}";
}
print ");\n\n";

# ----------------------------------------------------------------------------
#   Functions
# ----------------------------------------------------------------------------

print "// Functions\n";
my $global = $info->{'global'};
print "var s2funclib = new Array(";

my $cm = 0;
foreach my $func ( sort keys %$global ) {
    print "," if $cm++;

    print "\n\t{ name: '$func', type: '$global->{$func}{returntype}' }";
}
print ");\n\n";

# ----------------------------------------------------------------------------
#   Properties
# ----------------------------------------------------------------------------

print "// Properties\n";
my $props = $info->{'prop'};
print "var s2proplib = new Array(";

$cm = 0;
foreach my $prop ( sort keys %$props ) {
    print "," if $cm++;

    print "\n\t{ name: '$prop', type: '$props->{$prop}{type}' }";
}
print ");\n";

print "\n// End\n";

__END__

=head1 NAME

gens2editlib.pl - generate the LJ S2 editor library file for core layer 1

=head1 SYNOPSIS

gens2editlib.pl [-q] [-f core1.pl] [-l layerid] [-h] [-o ./s2library.js]

  Options consist of:
  -f, --file      specify path to layer compiled with s2compile.pl
  -h, --help      print this help message
  -l, --layerid   specify layer ID number with -f option; defaults to 1
  -q, --query     query local database to obtain S2 core layer
  -o, --output    specify where to put the generated JavaScript; defaults to
                  $LJHOME/htdocs/customize/advanced/s2edit/s2library.js
  
  You must specify either the -q or the -f option.

=cut
