/*
 * Copyright 1999 AT&T Labs -- Research
 * By receiving and using the code that follows, the user acknowledges
 * and agrees to keep the code confidential and use the code solely for
 * non-commercial research. The user further acknowledges and agrees that
 * the  code is not an official product of AT&T Corp., and is provided
 * on an "as is"  basis with no warranty, either express or implied, including
 * but not limited to implied warranties of merchantability and fitness
 * for a particular purpose, and any warranties of noninfringement.
 * The user shall use reasonable efforts to provide AT&T Laboratories
 * with reports of any errors, defects or suggestions for change and
 * improvements to the code.
 */

#pragma once

#include "Output.hpp"

class Settings;

/*
#define XMLOUTPUT_DEFAULT              0
#define XMLOUTPUT_LABELSTARTED         1
#define XMLOUTPUT_ATTRIBNAMESTARTED    2
#define XMLOUTPUT_ATTRIBVALUESTARTED   3
#define XMLOUTPUT_TEXTSTARTED          4
#define XMLOUTPUT_INITIALIZED          5
*/

#define XMLOUTPUT_INIT           0
#define XMLOUTPUT_OPENLABEL      1
#define XMLOUTPUT_OPENATTRIB     2
#define XMLOUTPUT_AFTERDATA      3
#define XMLOUTPUT_AFTERENDLABEL  4

#define XMLINDENT_NONE        0
#define XMLINDENT_WRAP        1
#define XMLINDENT_SPACES      3
#define XMLINDENT_TABS        4

/* abstract class */
class XMLOutput
{
public:
	virtual char OUTPUT_STATIC myCreateFile(char *fname)=0;
	virtual void OUTPUT_STATIC CloseFile()=0;
   virtual void OUTPUT_STATIC Init(unsigned char myindentation,unsigned char myvaluespacing=0,unsigned char mycoldelta=1)=0;

   virtual void OUTPUT_STATIC startElement(char *str,int len)=0;
   virtual void OUTPUT_STATIC endElement(char *str,int len)=0;
   virtual void OUTPUT_STATIC endEmptyElement()=0;
   virtual void OUTPUT_STATIC startAttribute(char *str,int len)=0;
   virtual void OUTPUT_STATIC endAttribute(char *str=NULL,int len=0)=0;
   virtual void OUTPUT_STATIC characters(char *str,int len)=0;
   virtual void OUTPUT_STATIC whitespaces(char *str,int len)=0;
   virtual void OUTPUT_STATIC attribWhitespaces(char *str,int len)=0;
};

/* subclass that creates an XML string using an Output instance, which writes to file or memory */
class XMLStringOutput: public XMLOutput
{
	Output *theoutput;
   OUTPUT_STATIC int curcol,coldelta;

   OUTPUT_STATIC struct ABC {
		unsigned char  status:3;
		unsigned char  content:2;
		unsigned char  isinattrib:1;
		unsigned char  indentation:5;
		unsigned char  valuespacing:1;
		unsigned char  attribwhitespace:1;
   } x;

   OUTPUT_STATIC void GotoNextLine(char moveright);

public:
   XMLStringOutput(Settings *settings);
   ~XMLStringOutput();

	void SetOutput(Output *outp);
	Output *GetOutput();

	virtual char OUTPUT_STATIC myCreateFile(char *fname);
	virtual void OUTPUT_STATIC CloseFile();
   virtual void OUTPUT_STATIC Init(unsigned char myindentation,unsigned char myvaluespacing=0,unsigned char mycoldelta=1);

   virtual void OUTPUT_STATIC startElement(char *str,int len);
   virtual void OUTPUT_STATIC endElement(char *str,int len);
   virtual void OUTPUT_STATIC endEmptyElement();
   virtual void OUTPUT_STATIC startAttribute(char *str,int len);
   virtual void OUTPUT_STATIC endAttribute(char *str=NULL,int len=0);
   virtual void OUTPUT_STATIC characters(char *str,int len);
   virtual void OUTPUT_STATIC whitespaces(char *str,int len);
   virtual void OUTPUT_STATIC attribWhitespaces(char *str,int len);
};

#ifdef WIN32

/* max tree depth */
#define MAXELEMS	1024

#import "msxml4.dll" 
using namespace MSXML2;

struct bla {
   MSXML2::IXMLDOMNodePtr node;
};

/* subclass that creates an MSXML instance */
class MSXMLOutput: public XMLOutput
{
   MSXML2::IXMLDOMDocumentPtr documentPtr;
	int curelemnum;
	bla *curelems;
   //int curcol,coldelta;
	char *filename;

   struct ABC {
		unsigned char  status:3;
		unsigned char  content:2;
		unsigned char  isinattrib:1;
		//unsigned char  indentation:5;
		//unsigned char  valuespacing:1;
		//unsigned char  attribwhitespace:1;
   } x;


public:
   MSXMLOutput();
   ~MSXMLOutput();

	virtual char myCreateFile(char *fname);
	virtual void CloseFile();
   virtual void Init(unsigned char myindentation,unsigned char myvaluespacing=0,unsigned char mycoldelta=1);

   virtual void startElement(char *str,int len);
   virtual void endElement(char *str,int len);
   virtual void endEmptyElement();
   virtual void startAttribute(char *str,int len);
   virtual void endAttribute(char *str=NULL,int len=0);
   virtual void characters(char *str,int len);
   virtual void whitespaces(char *str,int len);
   virtual void attribWhitespaces(char *str,int len);
};
#endif /* WIN32 */