note

	status: "See notice at end of class."
	date: "$Date$"
	revision: "$Revision$"

class SEQ_STRING inherit

	STRING
		rename
			precede as string_precede,
			prepend as string_prepend,
			mirrored as string_mirrored,
			mirror as string_mirror,
			share as string_share,
			wipe_out as string_wipe_out
		export
			{ANY}
				linear_representation
		undefine
			linear_representation
		redefine
			has, prune
		end

	SEQUENCE [CHARACTER]
		rename
			append as seq_append,
			item as current_item,
			index_of as index_of_occurrence,
			put as sequence_put,
			remove as remove_current_item
		export
			{NONE}
				sequence_put, seq_append
		undefine
			occurrences, out, copy, is_equal, prune_all,
			changeable_comparison_criterion
		redefine
			has, index_of_occurrence, prune
		select
			wipe_out, sequence_put
		end

create

	make

feature -- Access

	search_after (c: CHARACTER)
			-- Move cursor to first position
			-- (at or after current cursor position)
			-- where `current_item' and `c' are identical.
		do
			if not off then
				index := index_of (c, index)
				if index = 0 then
					index := count + 1
				end
			end
		end

	search_before (c: CHARACTER)
			-- Move cursor to greatest position at or before cursor
			-- where `current_item' and `c' are identical;
			-- go before if unsuccessful.
		local
			str: like Current
		do
			str := mirrored
			if not str.off then
				index := count + 1 - str.index_of (c, str.index)
				if index = count + 1 then
					index := 0
				end
			end
		end

	search_string_after (s: STRING; fuzzy: INTEGER)
			-- Move cursor to first position
			-- (at or after cursor position) where `substring
			-- (index, index + s.count)' and `s' are identical.
			-- Go after if unsuccessful.
			-- The 'fuzzy' parameter is the maximum allowed number
			-- of mismatches within the pattern. A 0 means an exact match.
		do
			if not off then
				index := fuzzy_index (s, index, fuzzy)
				if index = 0 then
					index := count + 1
				end
			end
		end

	search_string_before (s: STRING; fuzzy: INTEGER)
			-- Move cursor to first position
			-- (at or before cursor position) where `substring
			-- (index, index + s.count)' and `s' are identical.
			-- Go before if unsuccessful.
			-- The 'fuzzy' parameter is the maximum allowed number
			-- of mismatches within the pattern. A 0 means an exact match.
		local
			str_mirrored: like Current
			s_mirrored: STRING
		do
			if not off then
				str_mirrored := mirrored
				s_mirrored := s.mirrored
				index := count - str_mirrored.fuzzy_index (s_mirrored, count - index, fuzzy) + 1
				if index = count + 1 then
					index := 0
				else
					index := index - s.count + 1
				end
			end
		end

	current_item: CHARACTER
			-- Current item
		do
			Result := item (index)
		end

	index: INTEGER
			-- Index of `current_item', if valid
			-- Valid values are between 1 and `count' (if `count' > 0).

	index_of_occurrence (c: CHARACTER; i: INTEGER): INTEGER
			-- Index of `i'-th occurrence of `c'.
			-- 0 if none.
		local
			occur: INTEGER
		do
			if not is_empty then
				from
					Result := index_of (c, 1)
					if Result /= 0 then
						occur := 1
					end
				until
					(Result = 0) or else (occur = i)
				loop
					if Result /= count then
						Result := index_of (c, Result + 1)
						if Result /= 0 then
							occur := occur + 1
						end
					else
						Result := 0
					end
				end
			end
		ensure then
			Index_value: (Result = 0) or item (Result) = c
		end



	has (c: CHARACTER): BOOLEAN
			-- Does string include `c'?
		do
			if not is_empty then
				Result := (index_of (c, 1) /= 0)
			end
		end

feature -- Status report

	before: BOOLEAN
			-- Is there no valid cursor position to the left of cursor?
		do
			Result := index < 1
		end

	after: BOOLEAN
			-- Is there no valid cursor position to the right of cursor?
		do
			Result := index > count
		end

feature -- Cursor movement

	start
			-- Move to first position.
		do
			index := 1
		end

	finish
			-- Move to last position.
		do
			index := count
		end

	back
			-- Move to previous position.
		do
			index := index - 1
		end

	forth
			-- Move to next position.
		do
			index := index + 1
		end

feature -- Element change

	replace (c: CHARACTER)
			-- Replace current item by `c'.
		do
			put (c, index)
		end

	share (other: like Current)
			-- Make string share the text of `other'.
		require
			argument_not_void: other /= Void
		do
			string_share (other)
			index := other.index
		ensure
			shared_index: other.index = index
		end

	precede (c: CHARACTER)
			-- Add `c' at front.
		do
			string_precede (c)
			index := index + 1
		ensure
			new_index: index = old index + 1
		end

	prepend (s: STRING)
			-- Prepend a copy of `s' at front.
		require
			argument_not_void: s /= Void
		do
			string_prepend (s)
			index := index + s.count
		ensure
			new_index: index = old index + s.count
		end

feature -- Removal

	prune (c: CHARACTER)
			-- Remove first occurrence of `c'.
		local
			i: INTEGER
		do
			if count /= 0 then
				i := index_of (c, 1)
				if i /= 0 then
					remove (i)
				end
			end
		end

	remove_current_item
			-- Remove current item.
		do
			remove (index)
		end

	wipe_out
			-- Clear out all characters.
		do
			string_wipe_out
			index := 0
		end

feature -- Duplication

	mirrored: like Current
			-- Current string read from right to left.
			-- The result string has the same `capacity' and the
			-- same current position (i.e. the cursor is pointing
			-- at the same item)
		do
			Result := string_mirrored
			if not after then
				from
					Result.start
				until
					Result.index = count - index + 1
				loop
					Result.forth
				end
			end
		ensure
			mirrored_index: Result.index = count - index + 1
			same_count: Result.count = count
		--	reverse_entries:
		--	for all `i: 1..count, Result.item (i) = item (count + 1 - i)'
		end

	mirror
			-- Reverse the characters order.
			-- "Hello world" -> "dlrow olleH".
			-- The current position will be on the same item
			-- as before.
		do
			string_mirror
			index := count + 1 - index
		ensure
			same_count: count = old count
			mirrored_index: index = count - old index + 1
		--	reverse_entries:
		--	for all `i: 1..count, item (i) = old item (count + 1 - i)'
		end

feature {NONE} -- Inapplicable

	go_to (r: CURSOR)
			-- Go to position marked `r'.
		do
		end

note
	library:	"EiffelBase: Library of reusable components for Eiffel."
	copyright:	"Copyright (c) 1984-2006, Eiffel Software and others"
	license:	"Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
	source: "[
			 Eiffel Software
			 356 Storke Road, Goleta, CA 93117 USA
			 Telephone 805-685-1006, Fax 805-685-6869
			 Website http://www.eiffel.com
			 Customer support http://support.eiffel.com
		]"







end -- class SEQ_STRING