
package Text::Wigwam::Config::Class;

    use strict;
    use warnings;
    our $VERSION = '0.01';


	sub new {
		my $pkg = shift;
		return bless {
			conftag => {},    # Settings gleaned from template's config tag.
			inherit => undef, # Passed in by user or parent template.
			presets => {},    # Default settings.
			attribs => {
				 # Spawn behavior.
				confine => 0,
				 # Use presets for this class only when user settings are not provided.
				concede => 0,
				 # Parameters are ignored when generating an options hash if true.
				exclude => 0,
				 # Give priority to inherited settings over conftag settings.
				promote => 0,
			},
		}, $pkg;
	}

	sub set {
		my( $self, $attr, $value ) = @_;
		return $self->{$attr} = $value if exists $self->{$attr};
		warn "No such attribute - $attr in ".$self;
		return;
	}

	sub set_attrib {
		my( $self, $attr, $value ) = @_;
		return $self->{attribs}{$attr} = $value if exists $self->{attribs}{$attr};
		warn "No such attribute - $attr in ".$self;
		return;
	}

	sub conftag { return $_[0]->{conftag} }
	sub presets { return $_[0]->{presets} }
	sub inherit { return $_[0]->{inherit} }

	sub _spawn_presets { return $_[0]->presets }
	sub _spawn_conftag { return {} }
	 # Only a class' inherit parameters are passed to children when confine is true.
	sub _spawn_inherit { return $_[0]->_confined ? { $_[0]->_get_inherit } : $_[0]->generate }
	sub _spawn_attribs { return \%{$_[0]->{attribs}} }

	sub spawn {
		my $self = shift;
		return bless {
			conftag => _spawn_conftag,
			inherit => $self->_spawn_inherit,
			presets => $self->_spawn_presets,
			attribs => $self->_spawn_attribs,
		}, ref($self);
	}

	sub _get_presets { return $_[0]->_yields ? () : %{ $_[0]->presets || {} } }
	sub _get_conftag { return $_[0]->_exclude ? () : %{ $_[0]->conftag || {} }  }
	sub _get_inherit { return %{ $_[0]->inherit || {} } }

	sub generate {
		my $self = shift;
		return $self->_priority ? 
		 {
			$self->_get_presets,
			$self->_get_conftag,
			$self->_get_inherit, # Give priority to inherited settings
		 }
		:
		 {
			$self->_get_presets,
			$self->_get_inherit,
			$self->_get_conftag,
		 }
	}

	 ## Only a class' inherit parameters are passed to children when
	 ## confine is true.
	sub _confined { return $_[0]->{attribs}{confine} }

	 ## A class' preset parameters are completely ignored when
	 ## inherited settings are defined and concede is true.
	sub _yields { return $_[0]->{attribs}{concede} && defined $_[0]->{inherit} }

	 ## A class' parameters are not used to generate an
	 ## options hash when its exclude attribute is set.
	sub _exclude { return $_[0]->{attribs}{exclude} }

	 ## The promote attribute gives the particular class' inherit
	 ## settings priority over the conftag settings when generating
	 ## an options hash.
	sub _priority { return $_[0]->{attribs}{promote} }

1;

