// $Id: CViewer.cc,v 1.14 2003/05/10 06:46:50 ta_muto Exp $

#include <views/CViewer.h>
#include <views/CHttpHeaderTask.h>
#include <views/CTranslateTask.h>
#include <views/CIncludeTask.h>
#include <views/CCallTemplateTask.h>

#include <xupdate/CXUpdate.h>

wax::CViewer::~CViewer()
{
}

bool wax::CViewer::parse(CEnvironment* runenv, xmlNodePtr cur)
{
	xmlNsPtr ns = xmlSearchNsByHref(runenv->getDocPtr(), cur, CEnvironment::WAX);
	cur = cur->children;
	while(cur != NULL) {
		if(cur->ns == ns) {
			if(!xmlStrcmp(cur->name, (const xmlChar*) "output")) {
				if(isDisposed() == false) {
					xmlChar* ua = xmlGetProp(cur, (const xmlChar*) "ua");
					bool retCode = true;
					if(ua == NULL || xmlStrcasestr(runenv->getRequest()->getUserAgent(), ua) != NULL) {
						retCode = parseInternal(runenv, cur, ns);
					}
					if(ua != NULL)	xmlFree(ua);
					if(retCode == false)	return false;
				}
			}
		} else {
			xmlNsPtr nsXUpdate = xmlSearchNsByHref(runenv->getDocPtr(), cur, CEnvironment::XUPDATE);
			if(nsXUpdate != NULL)  {
				CXUpdate* task = CXUpdate::getInstance(runenv, cur);
				if(task == NULL)	return false;
				taskList.addItem(task);
			}
		}
		cur = cur->next;
	}
	return true;
}

bool wax::CViewer::parseInternal(CEnvironment* runenv, xmlNodePtr cur, xmlNsPtr ns)
{
	xmlChar* contentType = xmlGetProp(cur, (const xmlChar*)"content-type");
	if(contentType == NULL) {
		contentType = xmlStrdup((const xmlChar*)"text/html");
	}
	headList.addItem(new CHttpHeaderTask((const xmlChar*)"Content-type", contentType));
	xmlFree(contentType);

	cur = cur->children;
	while(cur != NULL) {
		if(cur->ns == ns) {
			ITask* task = NULL;
			bool bodyPart = true;
			
			task = findTask(cur, bodyPart);
			if(task != NULL) {
				if(task->parse(runenv, cur) == false) {
					delete task;
					return false;
				}
				if(bodyPart == true) {
					taskList.addItem(task);
				} else {
					headList.addItem(task);
				}
			}
		}
		cur = cur->next;
	}
	return true;
}

bool wax::CViewer::execute()
{
	ITask* task = (ITask*)headList.getHead();
	while(task != NULL) {
		if(task->execute() == false)	return false;
		task = (ITask*)task->getNext();
	}
	task = (ITask*)taskList.getHead();
	while(task != NULL) {
		if(task->execute() == false)	return false;
		task = (ITask*)task->getNext();
	}
	return true;
}

void wax::CViewer::output(IWriter* writer)
{
	ITask* task = (ITask*)headList.getHead();
	while(task != NULL) {
		task->output(writer);
		task = (ITask*)task->getNext();
	}
	writer->writeStr("\n");

	task = (ITask*)taskList.getHead();
	while(task != NULL) {
		task->output(writer);
		task = (ITask*)task->getNext();
	}
}

wax::ITask* wax::CViewer::findTask(xmlNodePtr cur, bool& bodyPart)
{
	ITask* task = NULL;
	if(!xmlStrcmp(cur->name, (const xmlChar*) "translate")) {
		task = new CTranslateTask();
	} else if(!xmlStrcmp(cur->name, (const xmlChar*) "include")) {
		task = new CIncludeTask();
	} else if(!xmlStrcmp(cur->name, (const xmlChar*) "header")) {
		task = new CHttpHeaderTask();
		bodyPart = false;
	} else if(!xmlStrcmp(cur->name, (const xmlChar*) "call-template")) {
		task = new CCallTemplateTask();
	}
	return task;
}
