#!/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;
}