#!/usr/bin/perl
#
#   png2wx - embed png in C++
#   written by Jan Engelhardt <jengelh [at] medozas de>, 2004 - 2008
#   http://jengelh.medozas.de/
#   released in the Public Domain
#

use Getopt::Long;
use strict;

exit(main(\@ARGV));

sub main ()
{
    my($cpp_file, $hpp_file, $hpp_include, $Marker, $main, $tmp);
    Getopt::Long::Configure(qw(bundling));
    GetOptions(
        "C=s" => \$cpp_file,
        "H=s" => \$hpp_file,
        "M=s" => \$Marker,
    );

    if ($cpp_file eq "" || $hpp_file eq "") {
        die "You need to specify -C, -H options.\n";
    }

    $hpp_include = $hpp_file;
    $hpp_include =~ s{^.*/}{};
    if ($Marker eq "") {
        $Marker = uc $hpp_file;
        $Marker =~ s{[^a-z]}{_}gi;
        print "Using marker $Marker\n";
    }

    #
    # C++ header
    #
    open(HPP, "> $hpp_file") || warn "Could not open $hpp_file: $!\n";
    $tmp = uc $hpp_file;
    $tmp =~ s/[^A-Z0-9]/_/g;
    print HPP "/* Autogenerated by png2wx.pl on ",
              scalar(localtime()), " */\n";
    print HPP <<"--EOF";
#ifndef $Marker
#define $Marker 1

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#   include <wx/wx.h>
#endif

extern void initialize_images(void);

--EOF

    #
    # C++/WX file
    #
    open(CPP, "> $cpp_file") || warn "Could not open $cpp_file: $!\n";
    print CPP "/* Autogenerated by png2wx.pl on ",
              scalar(localtime()), " */\n";
    print CPP <<"--EOF";
#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#   include <wx/wx.h>
#endif
#include <wx/mstream.h>
#include "$hpp_include"

--EOF

    #
    # Process files from the command line
    #
    foreach my $file (@ARGV) {
        my $base = $file;
        $base =~ s{^.*/}{};
        $base =~ s{(.*)\.(?:jpg|png)$}{$1}gis;
        $base =~ s/[^a-z0-9]/_/gio;

        print HPP "extern wxBitmap *_img_$base;\n";
        print CPP "wxBitmap *_img_$base;\n";

        $main .= "  {\n".
                 "      wxMemoryInputStream sm(\"".encoded($file)."\", ".(-s $file).");\n".
                 "      _img_$base = new wxBitmap(wxImage(sm));\n".
                 "  }\n";
    }

    #
    # Fixup C++ header
    #
    print HPP "\n", "#endif /* $Marker */\n";
    close HPP;

    print CPP
        "\n",
        "void initialize_images(void)\n{\n",
        $main,
        "   return;\n",
        "}\n";
    close CPP;
    return 0;
}

sub encoded ()
{
    my $file = shift @_;
    my $data;
    local *FH;

    if (!open(FH, "< $file")) {
        warn "Could not open $file: $!\n";
        return;
    }

    binmode FH;
    $data = join(undef, <FH>);
    $data =~ s/\\/\\\\/go;
    $data =~ s/([^\x07\x08\x0a\x0d\x20-\x7e])/sprintf "\\%03o", ord $1/egs;
    $data =~ s/\x07/\\a/gs;
    $data =~ s/\x08/\\b/gs;
    $data =~ s/\x09/\\t/gs;
    $data =~ s/\x0a/\\n/gs;
    $data =~ s/\x0b/\\v/gs;
    $data =~ s/\x0c/\\f/gs;
    $data =~ s/\x0d/\\r/gs;
    $data =~ s/\"/\\"/gs;
    # avoid trigraphs:
    $data =~ s/\?\?(?=[-\(\)<>=\/\'!])/?\\077/g;
    close FH;
    return $data;
}