/*******************************************************************************
 * This file is part of "Patrick's Programming Library", Version 7 (PPL7).
 * Web: http://www.pfp.de/ppl/
 *
 * $Author$
 * $Revision$
 * $Date$
 * $Id$
 *
 *******************************************************************************
 * Copyright (c) 2013, Patrick Fedick <patrick@pfp.de>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *    1. Redistributions of source code must retain the above copyright notice, this
 *       list of conditions and the following disclaimer.
 *    2. Redistributions in binary form must reproduce the above copyright notice,
 *       this list of conditions and the following disclaimer in the documentation
 *       and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER AND CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 *******************************************************************************/


#include "prolog.h"
#ifdef HAVE_STDIO_H
#include <stdio.h>
#endif
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#include "ppl7.h"
#include "ppl7-grafix.h"

namespace ppl7 {
namespace grafix {

/*!\class ImageFilter_PPM
 * \ingroup PPLGroupGrafik
 * \brief Import-/Export-Filter für PPM-Dateien
 */

ImageFilter_PPM::ImageFilter_PPM()
{
	//SaveAsASCII=false;
}

ImageFilter_PPM::~ImageFilter_PPM()
{
}


int ImageFilter_PPM::ident(FileObject &file, IMAGE &img)
{
	try {
		String line;
		file.seek(0);
		file.gets(line,64);
		if (line.left(3)=="P6\n") {		// Ja, ist ein PPM
			file.gets(line,64);				// Breite und Hoehe holen
			line.trim();
			while (line[0]=='#') {			// Es koennte sein, dass hier Kommentare drin sind
				file.gets(line,64);				// Breite und Hoehe holen
				line.trim();
			}
			Array a;
			a.explode(line," ");
			img.width=a.get(0).toInt();
			img.height=a.get(1).toInt();
			//file->Gets(tmpc,64);			// Farbtiefe holen, normalerweise 255
			img.bitdepth=24;
			img.colors=0x1000000;
			img.pitch=3*img.width;
			img.format=RGBFormat::X8R8G8B8;
			return 1;
		}
	} catch (...) {
		return 0;
	}
	return 0;
}

void ImageFilter_PPM::load(FileObject &file, Drawable &surface, IMAGE &img)
{
	String line;
	file.seek(0);
	file.gets(line,64);
	if (line.left(3)!="P6\n") throw UnknownImageFormatException();
	file.gets(line,64);				// Breite und Hoehe holen
	line.trim();
	while (line[0]=='#') {			// Es koennte sein, dass hier Kommentare drin sind
		file.gets(line,64);
		line.trim();
	}
	Array a;
	a.explode(line," ");
	img.width=a.get(0).toInt();
	img.height=a.get(1).toInt();
	file.gets(line,64);				// Farbtiefe holen, normalerweise 255
	//int farbtiefe;
	//farbtiefe=line.toInt();

	int x,y;
	ppluint8 r,g,b;
	ppluint64 pp=file.tell();
	const char *adresse;
	for (y=0;y<surface.height();y++) {
		adresse=file.map(pp,img.pitch);	// Zeile fuer Zeile einlesen
		pp+=img.pitch;
		for (x=0;x<surface.width();x++) {
			r=adresse[x*3];
			g=adresse[x*3+1];
			b=adresse[x*3+2];
			surface.putPixel(x,y,Color(r,g,b));
		}
	}
}

void ImageFilter_PPM::save (const Drawable &surface, FileObject &file, const AssocArray &param)
{
	Color farbe;
    //int haupt,unter,build;
	bool SaveAsASCII=false;
	if (param.exists("ascii")) SaveAsASCII=param.getString("ascii").toBool();


	if (surface.bitdepth()>8) {
		if (SaveAsASCII==false) file.puts("P6\n");
		else file.puts("P3\n");
		file.putsf("# Generated by PPL %u.%u.%u\n",PPL7_VERSION_MAJOR,PPL7_VERSION_MINOR,PPL7_VERSION_BUILD);
		file.putsf("# %s\n",PPL7_COPYRIGHT);
		file.putsf("%d %d\n",surface.width(),surface.height());
		file.putsf("%d\n",255);
		int c=0;
		for (int y=0;y<surface.height();y++) {
			for (int x=0;x<surface.width();x++) {
				farbe=surface.getPixel(x,y);
				ppluint8 r=(ppluint8)farbe.red();
				ppluint8 g=(ppluint8)farbe.green();
				ppluint8 b=(ppluint8)farbe.blue();
				if (SaveAsASCII==false) {
					file.write((char*)&r,1);
					file.write((char*)&g,1);
					file.write((char*)&b,1);
				} else {
					file.putsf("%u %u %u ",r,g,b);
					c++;
					if (c>7) {
						file.puts("\n");
						c=0;
					}
				}
			}
		}
		if (SaveAsASCII==true) {
			file.puts("\n");
		}
		return;
	} else {			// Farbpalette wurde benutzt
		throw UnsupportedFeatureException("ImageFilter_PPM::save with palette");
	}
	throw UnsupportedFeatureException("ImageFilter_PPM::save unsupported bitdepth");
}

String ImageFilter_PPM::name()
{
	return "PPM";
}
String ImageFilter_PPM::description()
{
	return "PPM";
}


} // EOF namespace grafix
} // EOF namespace ppl7


