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

#------------------------------------------------------------
# A validation constraint item.  A validation object used to
# validate constraints on data fields.
#
# Base Class:
#   Validate::Item
#
# Public methodas (defined or extended):
#   + Validate::Item::Constraint new()
#   + $scalar AUTOLOAD ( $scalar )
#------------------------------------------------------------

package Validate::Item::Constraint;
use strict;

use lib '/app/tools/common/lib';
use Common::Log;
use Common::RSApp;
use Common::Assert;

use lib '/app/tools/metadata/lib';
use base 'Validate::Item';

use Validate::Rule::Constraint::Nullable;
use Validate::Rule::Constraint::Regex;
use Validate::Rule::Constraint::List;
use Validate::Rule::Constraint::Length;
use Validate::Rule::Constraint::Between;
use Validate::Rule::Constraint::Date;
use Validate::Rule::Constraint::Integer;
use Validate::Rule::Constraint::ISRC;
use Validate::Rule::Constraint::ISRCRequired;
use Validate::Rule::Constraint::KeyValueList;
use Validate::Rule::Constraint::AdditionalArtistsList;
use Validate::Rule::Constraint::UniqueKeyValuePairs;
use Validate::Rule::Constraint::PriceTiersList;

use vars qw($AUTOLOAD);

###
# Define addition public accessors
###
use constant kClassAttributes => qw(name ok);

###
# Additional Rules to be used for this object.
###
use constant kValidationRules => qw( Validate::Rule::Constraint::Nullable
  Validate::Rule::Constraint::Regex
  Validate::Rule::Constraint::List
  Validate::Rule::Constraint::Length
  Validate::Rule::Constraint::Between
  Validate::Rule::Constraint::Date
  Validate::Rule::Constraint::Integer
  Validate::Rule::Constraint::ISRCRequired
  Validate::Rule::Constraint::ISRC
  Validate::Rule::Constraint::KeyValueList
  Validate::Rule::Constraint::AdditionalArtistsList
  Validate::Rule::Constraint::UniqueKeyValuePairs
  Validate::Rule::Constraint::PriceTiersList );

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

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

#------------------------------------------------------------
# $scalar AUTOLOAD( $scalar )
#
# Accessor methods for this object.  Methods to access the
# private data in this object.  Valid members are defined in
# the kClassAttributes constant.
#
# If a scalar is passed in this method will set the
# corrisponding private data member.
#
# This method always returns the value of the corrisponding
# private data member.
#
# This method is almost identical base class AUTOLOAD method
# except the method calls the parent AUTOLOAD instead of
# dying when an unknown attribute was seen.
#
# Parameters:
#   $scalar - Set the private data member to this value.
#             ** optional **
#
# Return:
#   $scalar - private memeber value
#------------------------------------------------------------
sub AUTOLOAD {
    my $self  = shift;
    my $value = shift;
    my $field = $AUTOLOAD;
    $field =~ s/.*://;    # Strips fully-qualified portion.

    my $attr = "_$field";

    return if $field eq 'DESTROY';    # skip DESTROY and all-cap methods

    unless ( $self->{_attributes}->{$field} ) {
        my $superior = "SUPER::$field";
        $self->$superior(@_);
    }

    # All preconditions are validated.  Let's do some work.

    # If a value is sent in, then set it.
    $self->{$attr} = $value
      if ($value);

    return $self->{$attr};
}

#------------------------------------------------------------
# Validate::Rule _init()
# Initialize the object.  This initializer creates a hash of
# valid public attributes and which validation rules should
# be added to this object.
#------------------------------------------------------------
sub _init {
    my ( $self, %args ) = @_;

    # Build a hash with our valid class attributes
    foreach ( (kClassAttributes) ) {
        $self->{_attributes}->{$_}++;
    }

    # Add validation rules for this object
    foreach ( (kValidationRules) ) {
        $self->_add_rule( rule => $_->new() );
    }

    # Set any attributes passed in
    foreach ( keys(%args) ) {
        $self->$_( $args{$_} ) if ( $self->{_attributes}->{$_} );
    }

    $self->SUPER::_init(%args);

    return $self;
}

1;
