#include <qfile.h>
#include <qtextstream.h>

#include <kaboutdata.h>
#include <kapplication.h>
#include <kcmdlineargs.h>
#include <kdebug.h>
#include <klocale.h>

#include <khtml_part.h>
#include <khtmlview.h>
#include <kparts/browserextension.h>
#include <kparts/part.h>

#include "dom/dom_doc.h"
#include "dom/dom_element.h"
#include "dom/dom_string.h"

#include "query.h"
#include "xpath_node.h"
#include "value.h"
#include "xpath_tests.h"

namespace XPath {

QTextStream log( stdout, IO_WriteOnly );

QTextStream &msg()
{
    return log;
}

void Tests::interactive( KHTMLPart *html )
{
    DOM::Document doc = html->document();

    printf("Entering interactive mode.\n"
	   "Use debug() to print to the console. Press C-d or C-c to exit.\n\n");

    char buffer[1000];
    FILE *in = fdopen(0, "r");
    
    while (1) {
	printf("XPath> ");
	if (!fgets(buffer, 999, in))
	    break;
	QString query( buffer );
	query = query.stripWhiteSpace();

	XPath::Query xp;
	XPath::Value v = xp.select( query, doc.documentElement() );
	XPath::String s = v.toString();

	msg() << "Value: " << v.qstring() << endl;
	msg() << "String: " << s.qstring() << endl;
    }
}

void Tests::test_ast( KHTMLPart *html )
{
    // XPathNode
    msg() << "XPathNode" << endl;
    XPath::XPathNode n;
    msg() << "\t" << n.qstring() << endl;

    // Axes
    msg() << endl << "Axes" << endl;
    XPath::Axis ax;
    for ( ushort i = 0 ; i < 16 ; i++ ) {
	ax = XPath::Axis( i );
	msg() << "\t" << ax.qstring() << endl;
    }

    // BinaryOps
    msg() << endl << "BinaryOps" << endl;
    XPath::BinaryOp bo;
    for ( ushort i = 0 ; i < 14 ; i++ ) {
	bo = XPath::BinaryOp( i );
	msg() << "\t" << bo.qstring() << endl;
    }

    // Functions
    msg() << endl << "Functions" << endl;
    XPath::FunctionCall f;
    for ( ushort i = 0 ; i < 28 ; i++ ) {
	f = XPath::FunctionCall( i );
	msg() << "\t" << f.qstring() << endl;
    }

    test_values( html );
}

void Tests::test_values( KHTMLPart * )
{
    msg() << endl << "Values" << endl;

    XPath::Value v;
    msg() << "\t" << v.qstring() << endl;

    XPath::Exception vx("oh my god, an error!");
    msg() << "\t" << vx.qstring() << endl;

    XPath::NodeSet vns;
    msg() << "\t" << vns.qstring() << endl;

    XPath::Boolean vb;
    msg() << "\t" << vb.qstring() << endl;

    XPath::Number vnu;
    msg() << "\t" << vnu.qstring() << endl;
    vnu = XPath::Number(12345);
    msg() << "\t" << vnu.qstring() << endl;
    vnu = XPath::Number(3.141);
    msg() << "\t" << vnu.qstring() << endl;

    XPath::String vs;
    msg() << "\t" << vs.qstring() << endl;
    vs = XPath::String( "testing a const char *" );
    msg() << "\t" << vs.qstring() << endl;
    vs = XPath::String( QString("testing a QString") );
    msg() << "\t" << vs.qstring() << endl;
}

}; // namespace XPath
