###################################################################
# Copyright (C) 2006 RoyaltyShare, Inc.  All Rights Reserved
# $Id$
###################################################################

package Common::XMLObject;

use strict;
use warnings;
use Carp;

use lib '/app/tools/common/lib';
use Common::WriteXML;
use Common::XMLWriter;
use Common::Assert;
use Common::Timer;

sub new {
    my ( $class, %args ) = @_;
    my $self = bless {}, $class;

    return $self->_init(%args);
}

sub _init {
    my ( $self, %args ) = @_;

    # If this is set to true, then do not output this
    # object's XML (nor any of it's contained objects...)
    # Note that there is also an accessor method to set this dynamically.
    #
    $self->{_skipXML} = $args{skipXML};

    # Make some space for any XML parameters we may have.
    #
    $self->{_xmlParams} = {};

    # Should we load this XMLObject's sub objects? (default to yes)
    #
    $self->{_loadSubs} = ( exists $args{loadSubs} ) ? $args{loadSubs} : 1;

    return $self;
}

sub writeXML {
    my ( $self, $xw, $tag, %extraParams ) = @_;

    return if $self->skipXML();

    if ($tag) {

        # If we have some extra params, we'll want to add those to our outgoing XMLParams;
        #
        my %outParams = $self->getXMLParams();
        foreach my $key ( keys %extraParams ) {
            $outParams{$key} = $extraParams{$key};
        }
        $xw->starttag( $tag, %outParams );
    }

    foreach my $key ( $self->_tags() ) {
        next if ( '_' eq substr( $key, 0, 1 ) );
        Common::WriteXML::writeXML( $xw, $self->{$key}, $key );
    }

    if ($tag) {
        $xw->endtag($tag);
    }
}

sub _tags {
    my ($self) = @_;

    return sort keys %{$self};
}

# These are for getting and setting the XML parameters.
# An XML parameter are extra key="value" pairs that appear in the tag,
# such as <Field id="0">
#
sub getXMLParams {
    my ($self) = @_;

    $self->{_xmlParams} = {} unless defined $self->{_xmlParams};
    return %{ $self->{_xmlParams} };
}

sub getXMLParam {
    my ( $self, $key ) = @_;

    $self->{_xmlParams} = {} unless defined $self->{_xmlParams};

    return $self->{_xmlParams}{$key};
}

sub setXMLParam {
    my ( $self, $key, $value ) = @_;

    if ( defined $value ) {
        $self->{_xmlParams}{$key} = $value;
    } else {
        delete $self->{_xmlParams}{$key} if ( exists $self->{_xmlParams}{$key} );
    }
}

sub skipXML {
    my $self = shift;

    if (@_) {
        my ($setFlag) = @_;
        $self->{_skipXML} = $setFlag;
    } else {
        return $self->{_skipXML};
    }
}

1;
