/*
 * This file is part of DesktopBSD, see the README file.
 *
 * Author: Pieringer Johannes <jpieringer@desktopbsd.net>
 *         (C) 2006
 *
 * Copyright: BSD, see the COPYING file included in this distribution
 *
 */

#include <qstring.h>
#include <qtextstream.h>
#include <stdio.h>

#include "grubbootentry.h"
#include "grubconfiguration.h"

const char *GrubBootentry::OstypesNames[5] =
   {"BSD", "Linux", "Windows", "Mac", "Other"
   };


/** Returns an instance of the GrubBootentry
 *	 @param comment, if the comment contais Type like '#[BSD]', the constructor sets the typ.
 */
GrubBootentry::GrubBootentry(QString value, const QString& comment, const QString& commentAfterCommand)
		: GrubCommand<QString>(value, comment, commentAfterCommand)
{
	this->unknownCommands = QPtrList<GrubCommand<QString> > ();

	QString _comment(comment);
	commentAfterCommand.stripWhiteSpace();

	bool set = false;

	for (int i = 0; i < (sizeof(OstypesNames) / sizeof(char*)); ++i)
	{
		if (_comment.contains(OstypesNames[i], false))
		{
			_comment.remove(QString("#[") + OstypesNames[i] + QString("]"), false);
			this->type = (Ostypes)i;
			set = true;
			break;
		}
	}

	if (!set)
		this->type = GrubBootentry::Other;

	this->comment = _comment;

	savedefault = NULL;
	kernel = NULL;
	chainloader = NULL;
	makeactive = NULL;
	initrd = NULL;
	root = NULL;
}

/** Returns the bootentry with his modifications in a QString
*/
QString GrubBootentry::toString()
{
	QString toString = "";

	if (this->comment.contains('\n', false) == 0)
		this->comment += "\n";

	toString += this->comment + "#[";
	toString += OstypesNames[this->type];
	toString += "]\n";

	toString += "title ";
	toString += this->getValue() += this->commentAfterCommand + "\n";

	switch (this->type)
	{
		case Linux:
			if (this->root != NULL)
			{
				this->root->setCommand("root");
				toString += this->root->toString();
			}

			if (this->kernel != NULL)
			{
				this->kernel->setCommand("kernel");
				toString += this->kernel->toString();
			}

			if (this->initrd != NULL)
			{
				this->initrd->setCommand("initrd");
				toString += this->initrd->toString();
			}

			for (GrubCommand<QString>* command = this->unknownCommands.first();
			      command;
			      command = this->unknownCommands.next())
				toString += command->toString();
			break;
		case BSD:
		case Mac:
		case Windows:
			if (this->root != NULL)
			{
				this->root->setCommand("root");
				toString += this->root->toString();
			}

			if (this->makeactive != NULL)
			{
				this->makeactive->setCommand("makeactive");
				toString += this->makeactive->toString();
			}
			else
				toString += "makeactive\n";

			if (this->chainloader != NULL)
			{
				this->chainloader->setCommand("chainloader");
				toString += this->chainloader->toString();
			}
			else
				toString += "chainloader +1\n";

			for (GrubCommand<QString>* command = this->unknownCommands.first();
			      command; command = this->unknownCommands.next())
				toString += command->toString();
			break;
		case Other:
			toString += lines += "\n";
			break;
	}

	if (this->getSavedefault() != NULL)
	{
		this->savedefault->setCommand("savedefault");
		toString += this->savedefault->toString();
	}
	return toString;
}

/**  Returns the value of the root command (contains the partition), can be NULL
	*/
QString* GrubBootentry::getRoot()
{
	if (this->root == NULL)
		return NULL;
	else
		return new QString(this->root->getValue());
}

/**  Returns the value of the kernel command (contains the path to the kernel on the root-partition),
 	* can be NULL
 	*/
QString* GrubBootentry::getKernel()
{
	if (this->kernel == NULL)
		return NULL;
	else
		return new QString(this->kernel->getValue());
}

/**  Returns NULL if the default bootentry is not saved.
*/
QString* GrubBootentry::getSavedefault()
{
	if (this->savedefault == NULL)
		return NULL;
	else
		return new QString(this->savedefault->getValue());
}

/**  Returns the value of the makeactive command, can be NULL
	*/
QString * GrubBootentry::getMakeactive()
{
	if (this->makeactive == NULL)
		return NULL;
	else
		return new QString(this->makeactive->getValue());
}

/**  Returns the value of the chainloader command, can be NULL
	*/
QString * GrubBootentry::getChainloader()
{
	if (this->chainloader == NULL)
		return NULL;
	else
		return new QString(this->chainloader->getValue());
}

/**  Returns the value of the initrd command, can be NULL
	*  This option is only used for linux-systems
	*/
QString * GrubBootentry::getInitrd()
{
	if (this->initrd == NULL)
		return NULL;
	else
		return new QString(this->initrd->getValue());
}

/**  Returns the type of the bootentry
	*/
GrubBootentry::Ostypes GrubBootentry::getOsType()
{
	return type;
}

/**  Returns the complete bootentry from the config WITHOUT modifications.
	*/
QString GrubBootentry::getLines()
{
	return lines;
}

/**  Sets the root value, if the value is NULL, the command is not set.
	*/
void GrubBootentry::setRoot(QString* root)
{
	if (root == NULL)
	{
		delete this->root;
		this->root = NULL;
	}
	else
		if (this->root == NULL)
		{
			this->root = new GrubCommand<QString>();
			this->root->setValue(QString(*root));
		}
		else
			this->root->setValue(*root);
}

/**  Sets the kernel value, if the value is NULL, the command is not set.
 */
void GrubBootentry::setKernel(QString* kernel)
{
	if (root == NULL)
	{
		delete this->kernel;
		this->kernel = NULL;
	}
	else
		if (this->kernel == NULL)
		{
			this->kernel = new GrubCommand<QString>();
			this->kernel->setValue(QString(*kernel));
		}
		else
			this->kernel->setValue(*kernel);
}

/**  Sets the initrd value, if the value is NULL, the command is not set.
 */
void GrubBootentry::setInitrd(QString* initrd)
{
	if (initrd == NULL)
	{
		delete this->initrd;
		this->initrd = NULL;
	}
	else
		if (this->initrd == NULL)
		{
			this->initrd = new GrubCommand<QString>();
			this->initrd->setValue(QString(*initrd));
		}
		else
			this->initrd->setValue(*initrd);
}

/**  Sets the savedefault value, if the value is NULL, the command is not set.
 */
void GrubBootentry::setSavedefault(QString* savedefault)
{
	if (savedefault == NULL)
	{
		delete this->savedefault;
		this->savedefault = NULL;
	}
	else
		if (this->savedefault == NULL)
		{
			this->savedefault = new GrubCommand<QString>();
			this->savedefault->setValue(QString(*savedefault));
		}
		else
			this->savedefault->setValue(*savedefault);
}

/**  Sets the makeactive value, if the value is NULL, the command is not set.
 */
void GrubBootentry::setMakeactive(QString * makeactive)
{
	if (makeactive == NULL)
	{
		delete this->makeactive;
		this->makeactive = NULL;
	}
	else
		if (this->makeactive == NULL)
		{
			this->makeactive = new GrubCommand<QString>();
			this->makeactive->setValue(QString(*makeactive));
		}
		else
			this->makeactive->setValue(*makeactive);
}

/**  Sets the chainloader value, if the value is NULL, the command is not set.
 */
void GrubBootentry::setChainloader(QString * chainloader)
{
	if (chainloader == NULL)
	{
		delete this->chainloader;
		this->chainloader = NULL;
	}
	else
		if (this->chainloader == NULL)
		{
			this->chainloader = new GrubCommand<QString>();
			this->chainloader->setValue(QString(*chainloader));
		}
		else
			this->chainloader->setValue(*chainloader);
}

/**  Sets the Os type
	*/
void GrubBootentry::setOsType(Ostypes type)
{
	this->type = type;
}

/**  Sets the complete textentry
	*/
void GrubBootentry::setLines(QString lines)
{
	this->lines = lines;
}

/**  Adds a new unknown command
	*/
void GrubBootentry::appendUnknownCommand(const GrubCommand< QString > * command)
{
	this->unknownCommands.append(command);
}


