use strict;

use XML::NamespaceSupport;
use XML::SAX::Base;

package W3C::XML::CMParser;
@W3C::SPDL::CMParser::ISA = qw(XML::SAX::Base);

sub TNS {
    my ($self, $value) = @_;
    return "{$self->{TNS}}$value";
}

sub NS {
    my ($self, $value) = @_;
    my ($ns, $prefix, $lname) = $self->{NSHelper}->process_element_name($value);
    return "{$ns}$lname";
}

sub start_element {
    my ($self, $data) = @_;
    my $name = $data->{LocalName};
    my $namespace = $data->{NamespaceURI};
    my $qualname = "{$namespace}$name";

    if (!exists $self->{Stack}[-1]{$qualname}) {
	my $stackStr = join("\n", (map {"<$_->{_name}>"} @{$self->{Stack}}), "<$qualname>");
	die "unexpected:\n$stackStr";
    }
    my $goto = $self->{Stack}[-1]{$qualname};
    push (@{$self->{Stack}}, $goto);
    if (my $code = $goto->{_start}) {
	&$code($self, $data);
    }
}

sub characters {
    my ($self, $data) = @_;
    my $chars = $data->{Data};
    my $goto = $self->{Stack}[-1];
    if ($chars =~ m/^\s*$/) {
	if (my $code = $goto->{_space}) {
	    &$code($self, $data);
	}	
    } elsif (my $code = $goto->{_chars}) {
	&$code($self, $data);
    } else {
	my $stackStr = join("\n", (map {"<$_->{_name}>"} @{$self->{Stack}}), $data->{Data});
	die "unexpected characters:\n$stackStr";
    }
}

sub end_element {
    my ($self, $data) = @_;
    my $name = $data->{LocalName};
    my $namespace = $data->{NamespaceURI};
    my $qualname = "{$namespace}$name";

    my $gotFrom = pop (@{$self->{Stack}});
    if (my $code = $gotFrom->{_end}) {
	&$code($self, $data);
    }
}


