/***************************************************************************
 *   Copyright (C) 2005 by Nicolas Ternisien                               *
 *   nicolas.ternisien@gmail.com                                           *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

//KDE includes
#include <kdebug.h>
#include <kiconloader.h>
#include <tdelocale.h>

//KSystemLog includes
#include "logLine.h"
#include "childLogLine.h"
#include "parentLogLine.h"

#include "logListItem.h"

#include "logMode.h"


#include "itemFactory.h"

LogListItem* ItemFactory::createLogListItem(TQListView* view, LogLine* line) {
	
	//If it is a parent Log Line
	if (line->isParentLogLine()==true)
		return(createParentItem(view, (ParentLogLine*)line));
		
	//If it's a child Log Line
	if (line->isChildLogLine()==true)
		return(createChildItem(view, (ChildLogLine*)line));
	
	/*
	//If it's a Samba mode item
	if (line->getType()==Globals::sambaMode->id) {
		kdDebug() << "Samba... Di Janero!!" << endl;
		LogListItem* item=createBasicItem(view, line);
		item->setMultiLinesEnabled(true);
	}
	*/
	
	//It's a normal Log Line
	return(createBasicItem(view, line));
	
}


LogListItem* ItemFactory::createParentItem(TQListView* view, ParentLogLine* line) {
	//kdDebug() << "Creating a parent item : " << line->getLogLevel()->name << endl;

	LogListItem* item=new LogListItem(view, line);
	
	//item->setExpandable(true);
	
	//Group by Log Level
	if (line->getGroupBy()==GROUP_BY_LOG_LEVEL) {
		item->setText(0, line->getLogLevel()->name);
		item->setPixmap(0, line->getLogLevel()->pixmap);
		
		if (line->getLogLevel()==Globals::informationLogLevel) {
			item->setOpen(true);
			view->ensureItemVisible(item);
		}
		else {
			item->setOpen(false);
		}

	}
	//Group by Day
	else if (line->getGroupBy()==GROUP_BY_DAY) {
		//TODO Move these tests to a dedicated static method (to be able to reuse it)
		TQDate today=TQDate::currentDate();
		TQDate yesterday=today.addDays(-1);
		
		TQDate date=line->getTime().date();
		
		if (date==today) {
			item->setText(0, i18n("Today"));
			item->setOpen(true);
			view->ensureItemVisible(item);
		}
		else if (date==yesterday) {
			item->setText(0, i18n("Yesterday"));
			item->setOpen(false);
		}
		else {
			item->setText(0, date.toString());
			item->setOpen(false);
		}
		
		item->setPixmap(0, SmallIcon(GROUP_BY_DAY_ICON));
	}
	//Group by Hour
	else if (line->getGroupBy()==GROUP_BY_HOUR) {
		TQString string(i18n("%1, %2h").arg(line->getTime().date().toString(), line->getTime().time().toString("h")));
		
		item->setText(0, string);
		item->setPixmap(0, SmallIcon(GROUP_BY_HOUR_ICON));
		
		TQDate today=TQDate::currentDate();
		TQTime time=TQTime::currentTime();
		if (line->getTime().date()==today && line->getTime().time().hour()==time.hour()) {
			kdDebug() << "Date equals, hour equals" << TQString(line->getTime().date().toString()) << " and " << TQString(line->getTime().time().toString()) << endl;
			item->setOpen(true);
			view->ensureItemVisible(item);
		}
		else {
			item->setOpen(false);
		}

	}
	//Group by Day
	else if (line->getGroupBy()==GROUP_BY_LOG_FILE) {
		item->setText(0, line->getOriginalFile());
		item->setPixmap(0, SmallIcon(GROUP_BY_LOG_FILE_ICON));
	}
	//Group by a specific column
	else {
		int index=ParentLogLine::getGroupedColumnIndex(line->getColumns(), line->getGroupByColumn());
		
		TQStringList& list=line->getItemList();

		if (index<0 || index>=(int)list.size())
			item->setText(0, i18n("none"));
		else
			item->setText(0, list[index]);
			
		item->setPixmap(0, SmallIcon(GROUP_BY_COLUMN_ICON));
	}

	return(item);
}

LogListItem* ItemFactory::createChildItem(TQListView* /*view*/, ChildLogLine* line) {
	
	LogListItem* parent=line->getParent()->getLogListItem();
	
	if (parent==NULL)
		kdDebug() << "Parent log list item NULL !!!" << endl;
	
	//kdDebug() << "The log level of the parent is " << parent->getLogLine()->getLogLevel()->name << endl;
	
	LogListItem* item=new LogListItem(parent, line);
	
	initItem(item);
	
	return(item);
}

LogListItem* ItemFactory::createBasicItem(TQListView* view, LogLine* line) {
	LogListItem* item=new LogListItem(view, line);
	
	initItem(item);
	
	return(item);
}

void ItemFactory::initItem(LogListItem* item) {
	LogLine* line=item->getLogLine();
	
	//If it's a Xorg Log Line
	if (line->getType() == Globals::xorgMode->id) {
		initXorgItem(item);
		return;
	}
	
	//Default Item
	initDefaultItem(item);

}

void ItemFactory::initDefaultItem(LogListItem* item) {
	LogLine* line=item->getLogLine();
	
	item->setText(0, line->getTime().toString(TQt::LocalDate));
	
	int i=1;
	TQStringList& labels=line->getItemList();
	TQStringList::iterator it;
	for(it=labels.begin(); it!=labels.end(); ++it) {
		item->setText(i, *it);
		i++;
	}
	
	item->setPixmap(0, line->getLogLevel()->pixmap);
}


void ItemFactory::initXorgItem(LogListItem* item) {
	LogLine* line=item->getLogLine();
	
	item->setText(0, "");
	
	int i=1;
	TQStringList& labels=line->getItemList();
	TQStringList::iterator it;
	for(it=labels.begin(); it!=labels.end(); ++it) {
		item->setText(i, *it);
		i++;
	}

	item->setPixmap(0, line->getLogLevel()->pixmap);

}



TQString ItemFactory::createFormattedText(LogLine* line) {
		
	//Special case if this is a ParentLogLine (Group By feature)
	if (line->isParentLogLine())
		return(createParentFormattedText(line));
	
	
	if (line->getType() == Globals::cronMode->id)
		return(createCronFormattedText(line));
	
	if (line->getType() == Globals::xorgMode->id)
		return(createXorgFormattedText(line));
	
	if (line->getType() == Globals::acpidMode->id)
		return(createAcpidFormattedText(line));
	
	if (line->getType() == Globals::cupsMode->id)
		return(createCupsFormattedText(line));
	
	if (line->getType() == Globals::cupsAccessMode->id)
		return(createCupsAccessFormattedText(line));
	
	if (line->getType() == Globals::apacheMode->id)
		return(createApacheFormattedText(line));
	
	if (line->getType() == Globals::apacheAccessMode->id)
		return(createApacheAccessFormattedText(line));
		
	if (line->getType() == Globals::sambaMode->id)
		return(createSambaFormattedText(line));
	
	//Returns the default formating
	return(createDefaultFormattedText(line));

}

TQString ItemFactory::createToolTipText(LogLine* line) {
	if (line->getType() == Globals::xorgMode->id)
		return(createXorgToolTipText(line));
	else
		return(createDefaultToolTipText(line));

}

TQString ItemFactory::createParentFormattedText(LogLine* line) {
	TQString result;
	
	ParentLogLine* parent=(ParentLogLine*) line;
	
	//All Group By cases are showed here
	if (parent->getGroupBy()==GROUP_BY_LOG_LEVEL) {
		result.append(i18n("<div align='center'><b>Group:</b> %1</div>").arg(line->getLogLevel()->name));
	}
	else if (parent->getGroupBy()==GROUP_BY_DAY) {
		result.append(i18n("<div align='center'><b>Group:</b> %1</div>").arg(line->getTime().date().toString()));
	}
	else if (parent->getGroupBy()==GROUP_BY_HOUR) {
		TQString string(i18n("%1, %2 hour").arg(line->getTime().date().toString(), line->getTime().time().toString("h")));
		result.append(i18n("<div align='center'><b>Group:</b> %1</div>").arg(string));
	}
	else if (parent->getGroupBy()==GROUP_BY_LOG_FILE) {
		result.append(i18n("<div align='center'><b>Group:</b> %1</div>").arg(line->getOriginalFile()));
	}
	else {
		TQStringList& list=line->getItemList();
		int index=ParentLogLine::getGroupedColumnIndex(parent->getColumns(), parent->getGroupByColumn());
		if (index<0 || index>=(int) list.size())
			result.append(i18n("<div align='center'><b>Group:</b> none</div>"));
		else
			result.append(i18n("<div align='center'><b>Group:</b> %1</div>").arg(list[index]));
	}
	
	return(result);
}


TQString ItemFactory::createCronFormattedText(LogLine* line) {
	TQString result;
	TQStringList& items=line->getItemList();
	
	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Hostname:"), items[0]));
	result.append(labelMessageFormat(i18n("Process:"), items[1]));
	result.append(labelMessageFormat(i18n("User:"), items[2]));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));
	result.append(labelMessageFormat(i18n("Original file:"), line->getOriginalFile()));

	result.append("</table>");

	return(result);
}

TQString ItemFactory::createDefaultFormattedText(LogLine* line) {
	TQString result;
	
	TQStringList& items=line->getItemList();
	
	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Hostname:"), items[0]));
	result.append(labelMessageFormat(i18n("Process:"), items[1]));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));
	result.append(labelMessageFormat(i18n("Original file:"), line->getOriginalFile()));

	result.append("</table>");

	return(result);
}

TQString ItemFactory::createAcpidFormattedText(LogLine* line) {
	TQString result;
	
	TQStringList& items=line->getItemList();
	
	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));
	result.append(labelMessageFormat(i18n("Type:"), items[0]));

	result.append("</table>");

	return(result);
}

TQString ItemFactory::createCupsFormattedText(LogLine* line) {
	TQString result;
	
	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));

	result.append("</table>");

	return(result);
}

TQString ItemFactory::createCupsAccessFormattedText(LogLine* line) {
	TQString result;
	
	TQStringList& items=line->getItemList();
	
	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));
	result.append(labelMessageFormat(i18n("Hostname:"), items[0]));
	result.append(labelMessageFormat(i18n("Identification:"), items[1]));
	result.append(labelMessageFormat(i18n("Username:"), items[2]));
	result.append(labelMessageFormat(i18n("HTTP Response:"), items[3]));
	result.append(labelMessageFormat(i18n("Bytes Sent:"), items[4]));

	result.append("</table>");

	return(result);
}


TQString ItemFactory::createApacheFormattedText(LogLine* line) {
	TQString result;
	
	TQStringList& items=line->getItemList();
	
	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));
	result.append(labelMessageFormat(i18n("Client:"), items[0]));

	result.append("</table>");

	return(result);
}

TQString ItemFactory::createApacheAccessFormattedText(LogLine* line) {
	TQString result;
	
	TQStringList& items=line->getItemList();
	
	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));
	result.append(labelMessageFormat(i18n("Hostname:"), items[0]));
	result.append(labelMessageFormat(i18n("Identification:"), items[1]));
	result.append(labelMessageFormat(i18n("Username:"), items[2]));
	result.append(labelMessageFormat(i18n("HTTP Response:"), items[3]));
	result.append(labelMessageFormat(i18n("Bytes Sent:"), items[4]));
	result.append(labelMessageFormat(i18n("Agent Identity:"), items[5]));
	result.append(labelMessageFormat(i18n("HTTP Request:"), items[6]));

	result.append("</table>");

	return(result);
}


TQString ItemFactory::createSambaFormattedText(LogLine* line) {
	TQString result;
	
	TQStringList& items=line->getItemList();
	
	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));
	result.append(labelMessageFormat(i18n("Source File:"), items[0]));
	result.append(labelMessageFormat(i18n("Function:"), items[1]));
	result.append(labelMessageFormat(i18n("Line:"), items[2]));

	result.append("</table>");

	return(result);
}


TQString ItemFactory::createXorgFormattedText(LogLine* line) {
	//It uses the same formating than the Tooltip
	return(createXorgToolTipText(line));
}

TQString ItemFactory::createDefaultToolTipText(LogLine* line) {
	TQString result;

	result.append("<table>");
	
	result.append(labelMessageFormat(i18n("Date:"), line->getTime().toString(TQt::LocalDate)));
	result.append(labelMessageFormat(i18n("Level:"), line->getLogLevel()->name));
	result.append(labelMessageFormat(i18n("Original file:"), line->getOriginalFile()));

	result.append("</table>");

	return(result);
}

TQString ItemFactory::createXorgToolTipText(LogLine* line) {
	TQString result;
	
	TQStringList& items=line->getItemList();
	
	result.append("<table>");
	
	if (items[0].isEmpty())
		result.append(labelMessageFormat(i18n("Type:"), i18n("none")));
	else
		result.append(labelMessageFormat(i18n("Type:"), items[0]));
	
	result.append(labelMessageFormat(i18n("Original file:"), line->getOriginalFile()));

	result.append("</table>");

	return(result);
}




TQString ItemFactory::labelMessageFormat(TQString label, TQString value) {
	return ("<tr><td align='right'><b><nobr>" + label + "</nobr></b></td><td>" + messageFormat(value) + "</td></tr>");
}

TQString ItemFactory::messageFormat(TQString& message) {
	TQString transformation(message);
	transformation.replace(TQRegExp("&"), "&amp;");
	transformation.replace(TQRegExp("<"), "&lt;");
	transformation.replace(TQRegExp(">"), "&gt;");
	return(transformation);
}
