require "rexml/namespace"

module REXML
	## 
	# Defines an Element Attribute; IE, a attribute=value pair, as in:
	# <element attribute="value"/>.  Attributes can be in their own
	# namespaces.  General users of REXML will not interact with the
	# Attribute class much.
	class Attribute
		include Node
		include Namespace

		attr_accessor :value			# The value of the attribute
		attr_reader :element			# The element to which this attribute belongs
		PATTERN = /\s*((?:\w[\w-]*:)?\w[\w-]*)\s*=\s*(["'])(.*?)\2/um

		##
		# Constructor.
		# @param first if an Attribute, clones the attribute.  If a String,
		# uses this as the attribute name.  If a Source, parses the source
		# for key=value pairs.
		# @param second (optional) if first is an Attribute or a Source, this 
		# can be the Element to which the Attribute belongs.  If first is a 
		# String, this is the value part of the attribute.  
		# @param parent (optional) if first is a String, this can be the parent
		# to which this attribute belongs
		def initialize( first, second=nil, parent=nil )
			@element = nil
			if first.kind_of? Attribute
				self.name = first.name
				@value = first.value
				if second.kind_of? Element
					@element = element
				else
					@element = first.element
				end
			elsif first.kind_of? String
				@element = parent if parent.kind_of? Element
				self.name = first
				@value = second
			elsif first.kind_of? Source
				@element = second if second.kind_of? Element
				md = first.match(PATTERN, true )
				self.name, @value = md[1],md[3]
			else
				raise "illegal argument #{first.type} to Attribute constructor"
			end
			@value = read_with_substitution @value
		end

		def prefix
			pf = super
			if pf == ""
				pf = @element.prefix if @element
			end
			pf
		end

		def namespace arg=nil
			arg = prefix if arg.nil?
			@element.namespace arg
		end

		##
		# @return true if other is an Attribute and has the same name and value,
		# false otherwise.
		def ==( other )
			other.kind_of?(Attribute) and other.name==name and other.value==@value
		end

		## Creates (and returns) a hash from both the name and value
		def hash
			name.hash + value.hash
		end

		def to_s
			val = ""
			write_with_substitution( val, @value )
			"#@expanded_name='#{val}'"
		end

		def clone
			Attribute.new self
		end

		##
		# Sets the element of which this object is an attribute
		# @return this attribute
		def element=( element )
			@element = element
			self
		end

		## Removes this Attribute from the tree, and returns true if successfull
		def remove
			@element.attributes.delete self.name unless @element.nil?
		end

		## Writes this attribute (EG, puts 'key="value"' to the output)
		def write( output, indent=0 )
			output << to_s
		end
	end
end
