#!/usr/bin/perl

use strict;

#BEGIN {unshift@INC,('../../..');}
use W3C::XML::XmlParser;
use W3C::XML::InputSource;
use W3C::XML::XmlElementTree;
use W3C::XML::HandlerBase;
use W3C::Util::Exception;

new W3C::XML::elementdecl('test1', 0, 0, '((a,(b,c)*)|(d,e)+)')->showElementdeclStatus;
new W3C::XML::elementdecl('test1', 0, 0, '((a,(b,c)*))')->showElementdeclStatus;
new W3C::XML::elementdecl('test1', 0, 0, '((a,(b,c)*)|d,e)')->showElementdeclStatus;
#new W3C::XML::elementdecl('test1', 0, 0, '((a,b)*)'.',/test1')->showElementdeclStatus;

eval {
    &main(\@ARGV);
}; if ($@) {if ($@) {if (my $ex = &catch('W3C::Util::Exception')) {
    print $ex->toString;
    die "\n";
} else {die $@;}}}

sub main {
    my ($args) = @_;
    my ($source, @lookFors) = @$args; # ($args->[0], @$args[1..$#$args]);

#    my $t0 = time; print "start\n";

    my $xmlParser = new W3C::XML::PerlXmlParser;
#    my $xmlParser = new W3C::XML::ExpatXmlParser;
    my $errorHandler = new SAXErrorHandler($xmlParser);

    # it's easiest to stick all your document handlers in a W3C::XML::HandlerList
    my $xmlElementTree = new W3C::XML::XmlElementTree;
    my $handlerList = new W3C::XML::HandlerList(-documentHandlers => [$xmlElementTree], -errorHandlers => [$errorHandler]);

    # also play with DTD enforcing document handler stream
    my $dtdDB = new W3C::XML::DtdDB($errorHandler, $xmlParser); # cheat 'cause we know it's a locator
    $xmlParser->setDTDDatabase($dtdDB);

    # use a W3C::XML::OldNamespaceHandler stream to map from prefix:tag - pass to tree serializer
    # so it translate back for pretty-printing
    my $namespaceHandler = new W3C::XML::OldNamespaceHandler(-documentHandler => $handlerList);
    $xmlElementTree->setNamespaceHandler($namespaceHandler);

    # and have the W3C::XML::HandlerList be the document handler and the error handler
    $xmlParser->setDocumentHandler(new W3C::XML::DtdEnforcer($namespaceHandler, $dtdDB));
    $xmlParser->setErrorHandler($handlerList);

    # assign a URI to the XML in InputSorce and parse it
    my $inputSource = new W3C::XML::FileInputSource($source);
    eval {$xmlParser->parse($inputSource);};
    if ($@) {
    	die $@.' at line '.$xmlParser->getLineNumber.' column '.$xmlParser->getColumnNumber;
    }
#    my $t1 = time; print $t1-$t0,"\n";

    # some ways to show the result
    print $xmlElementTree->show('');
#    my $t2 = time; print $t2-$t0,"\n";
    return;
}

package SAXErrorHandler;

sub new {
    my $class = shift;
    my $proto = ref $class || $class;
    my $self = {};
    bless($self, $proto);
    $self->{XML_PARSER} = shift;
    return $self;
}

sub makeString {
    my ($self, $exception) = @_;
    my $ret = $exception->toString;
    if ($exception->isa('W3C::Rdf::RdfDBException')) {
	$ret .= ' at line '.$self->{XML_PARSER}->getLineNumber.' column '.$self->{XML_PARSER}->getColumnNumber;
    }
    return $ret;
}

sub warning {
    my ($self, $exception) = @_;
    print 'warning: '.$self->makeString($exception)."\n";
}

sub error {
    my ($self, $exception) = @_;
    warn 'error: '.$self->makeString($exception)."\n";
}

sub fatalError {
    my ($self, $exception) = @_;
    die 'fatalError: '.$self->makeString($exception)."\n";
}

