note
	description	: "Main window for this application"
	status: "See notice at end of class."
	legal: "See notice at end of class."
	author		: "Generated by the New Vision2 Application Wizard."
	date		: "$Date$"
	revision	: "1.0.0"

class
	MAIN_WINDOW

inherit
	EV_TITLED_WINDOW
		redefine
			initialize,
			is_in_default_state
		end

	INTERFACE_NAMES
		export
			{NONE} all
		undefine
			default_create, copy
		end

	EV_LAYOUT_CONSTANTS
		export
			{NONE} all
		undefine
			default_create, copy
		end

create
	default_create

feature {NONE} -- Initialization

	initialize
			-- Build the interface for this window.
		local
			l_acc: EV_ACCELERATOR
		do
			Precursor {EV_TITLED_WINDOW}

			create pixmap_window
			create code_producer

				-- Create and add the menu bar.

			build_tool_bar

			build_main_container
			extend (main_container)

				-- Execute `request_close_window' when the user clicks
				-- on the cross in the title bar.
			close_request_actions.extend (agent request_close_window)

				-- Set the title of the window
			set_title (Window_title)
			set_icon_pixmap ((create {SUN_ICON}.make).to_pixmap)

			tool_bar.file_drop_actions.extend (agent on_file_dropped)
			class_name_field.file_drop_actions.extend (agent on_file_dropped)
			text_panel.file_drop_actions.extend (agent on_file_dropped)

			create l_acc.make_with_key_combination (create {EV_KEY}.make_with_code ({EV_KEY_CONSTANTS}.key_a), True, False, False)
			l_acc.actions.extend (agent select_all)
			accelerators.extend (l_acc)

			create l_acc.make_with_key_combination (create {EV_KEY}.make_with_code ({EV_KEY_CONSTANTS}.key_s), True, False, False)
			l_acc.actions.extend (agent save)
			accelerators.extend (l_acc)

			saved := True
			toggle_save

			default_title := title

				-- Set the initial size of the window
			set_size (500, 600)
		end

	is_in_default_state: BOOLEAN
			-- Is the window in its default state
			-- (as stated in `initialize')
		do
			Result := (width = Window_width) and then
				(height = Window_height) and then
				(title.is_equal (Window_title))
		end


feature {NONE} -- Menu Implementation

	standard_menu_bar: EV_MENU_BAR
			-- Standard menu bar for this window.

	file_menu: EV_MENU
			-- "File" menu for this window (contains New, Open, Close, Exit...)

	tool_bar: EV_TOOL_BAR
			-- Tool bar

feature {NONE} -- Implementation, Close event

	request_close_window
			-- The user wants to close the window
		do
			destroy;
			(create {EV_ENVIRONMENT}).application.destroy
		end

feature {NONE} -- Implementation

	main_container: EV_VERTICAL_BOX
			-- Main container (contains all widgets displayed in this window)

	build_main_container
			-- Create and populate `main_container'.
		require
			main_container_not_yet_created: main_container = Void
		local
			hb: EV_HORIZONTAL_BOX
			vb: EV_VERTICAL_BOX
		do
			create main_container
			create hb
			hb.set_padding_width (default_padding_size)
			hb.extend (tool_bar)
			hb.disable_item_expand (tool_bar)
			create class_name_field
			class_name_field.return_actions.extend (agent
					local
						t: STRING_32
					do
						if class_name /= Void then
							t := class_name_field.text
							if t /= Void and then not t.is_equal (class_name) then
								class_name := t.as_upper
								build_file (origin_pixmap)
								text_panel.set_text (class_file)
							end
						end
					end
				)
			create vb
			vb.set_border_width (small_border_size)
			vb.extend (create {EV_CELL})
			vb.extend (class_name_field)
			vb.extend (create {EV_CELL})
			vb.disable_item_expand (class_name_field)
			hb.extend (vb)
			main_container.extend (hb)
			main_container.disable_item_expand (hb)

			create text_panel
			text_panel.set_font (create {EV_FONT}.make_with_values ({EV_FONT_CONSTANTS}.family_screen, {EV_FONT_CONSTANTS}.weight_regular, {EV_FONT_CONSTANTS}.shape_regular, 12))
			text_panel.change_actions.extend (agent set_change (True))
			main_container.extend (text_panel)
		ensure
			main_container_created: main_container /= Void
		end

	build_tool_bar
			-- Build tool bar
		local
			tool_bar_item: EV_TOOL_BAR_BUTTON
			l_color: EV_COLOR
			l_save_icon: SAVE_ICON
			l_copy_to_clipboard_icon: COPY_TO_CLIPBOARD_ICON
			l_image_icon: IMAGE_ICON
		do
			create l_save_icon.make_top_to_bottom (l_color)
			create l_copy_to_clipboard_icon.make

			create l_image_icon.make_top_to_bottom (Void)
			create tool_bar

			tool_bar.extend (create {EV_TOOL_BAR_SEPARATOR})

			create tool_bar_item.make_with_text ("Open")
			tool_bar_item.set_pixmap (l_image_icon)
			tool_bar_item.select_actions.extend (agent open)
			tool_bar.extend (tool_bar_item)

			create save_button.make_with_text ("Save")
			save_button.set_pixmap (l_save_icon)
			save_button.select_actions.extend (agent save)
			tool_bar.extend (save_button)

			create copy_to_clipboard_button.make_with_text ("Copy")
			copy_to_clipboard_button.set_pixmap (l_copy_to_clipboard_icon.to_pixmap)
			copy_to_clipboard_button.select_actions.extend (agent copy_to_clipboard)
			tool_bar.extend (copy_to_clipboard_button)
		end

	open_file_dialog: EV_FILE_OPEN_DIALOG
			-- Dialog for selecting an image

	save_file_dialog: EV_FILE_SAVE_DIALOG
			-- Dialog for saving classes

	class_name_field: EV_TEXT_FIELD
			-- Text field for class name

	text_panel: EV_TEXT
			-- Text panel to present generated class.

	save_button: EV_TOOL_BAR_BUTTON
			-- Tool bar button for saving a class

	copy_to_clipboard_button: EV_TOOL_BAR_BUTTON
			-- Tool bar button to copy to clipboard

	changed: BOOLEAN
			-- Text in `text_panel' changed?

	saved: BOOLEAN
			-- Current class text saved?

	on_file_dropped (fns: LIST [STRING_32])
		do
			if fns.count = 1 then
				open_image_file (Void, fns.first)
			end
		end

	open
			-- Execute when push open button.
		do
			create open_file_dialog.make_with_title ("Open Image")
			open_file_dialog.open_actions.extend (agent open_image)
			open_file_dialog.filters.extend (["*.png","PNG Image (*.png)"])
			open_file_dialog.filters.extend (["*.bmp","BMP Image (*.bmp)"])
			open_file_dialog.filters.extend (["*.jpg","JPG Image (*.jpg)"])
			open_file_dialog.filters.extend (["*.gif","GIF Image (*.gif)"])
			open_file_dialog.filters.extend (["*.*","All files"])
			open_file_dialog.show_modal_to_window (Current)
		end

	save
			-- Execute when push save button.
		local
			l_file: PLAIN_TEXT_FILE
		do
			if file_path /= Void then
				if not saved then
					create save_file_dialog.make_with_title ("Save created class")
					save_file_dialog.filters.extend (["*.e", "Eiffel class (*.e)"])
					save_file_dialog.filters.extend (["*", "All files (*.*)"])
					save_file_dialog.set_file_name (class_name.as_lower + ".e")
					save_file_dialog.save_actions.extend (agent save_file)
					save_file_dialog.show_modal_to_window (Current)
				else
					if changed then
						create l_file.make_with_name (file_path)
						l_file.open_write
						l_file.put_string (class_file)
						l_file.close
						set_change (False)
					end
				end
			end
		end

	copy_to_clipboard
			-- copy to clipboard
		do
			ev_application.clipboard.set_text (class_file)
		end

	open_image
			-- Execute when an image is selected in open dialog.
		do
			open_image_file (open_file_dialog.file_title, open_file_dialog.file_name)
		end

	open_image_file	(sfn: STRING_32; fn: STRING_32)
			-- Execute when an image is opened
			-- if `sfn' is Void retrieve the short file name from `fn'.
		local
			prompt: EV_WARNING_DIALOG
			subfix: STRING_32
		do
			if sfn = Void then
				create file_name.make_from_string (fn.substring (fn.last_index_of (Operating_environment.directory_separator, fn.count) + 1, fn.count))
			else
				create file_name.make_from_string (sfn)
			end
			if file_name.has ('.') then
				set_busy_pointer
				subfix := file_name.as_lower
				subfix.keep_tail (file_name.count - file_name.last_index_of ('.', file_name.count))

				create origin_pixmap
				origin_pixmap.set_with_named_file (fn)

				pixmap_window.set_title (file_name)

				build_class_name (file_name)
				class_name_field.set_text (class_name)

				build_file (origin_pixmap)
				saved := False
				toggle_save
				text_panel.set_text (class_file)
				create file_path.make_from_string (fn)

				set_title (default_title + " -- (Text not saved)")

					-- Load picture and show in the window.
				pixmap_window.set_pixmap (origin_pixmap)
				pixmap_window.show
				pixmap_window.update_size
				set_standard_pointer
			else
				create prompt.make_with_text ("Is it an image file?")
				prompt.show_modal_to_window (Current)
			end
		end

	save_file
			-- Excute when saving in save dialog.
		local
			l_file: PLAIN_TEXT_FILE
		do
			create l_file.make_with_name (save_file_dialog.file_name)
			l_file.open_write
			l_file.put_string (class_file)
			l_file.close
			set_change (False)
			saved := True
			set_title (default_title + " -- " + save_file_dialog.file_name)
		end

	select_all
			-- Select all text in `text_panel'.
		do
			text_panel.select_all
		end

	build_class_name (a_file_name: STRING_32)
			-- Build class name from `a_file_name'
		local
			l_index: INTEGER
		do
			class_name := file_name.as_upper
			l_index := class_name.last_index_of ('.', class_name.count)
			if l_index > 0 then
				class_name.keep_head (l_index - 1)
			end
			if not class_name.is_valid_as_string_8 or else not (create {EIFFEL_SYNTAX_CHECKER}).is_valid_class_name (class_name.as_string_8) then
				class_name := {STRING_32} "NEW_CLASS"
			end
		end

feature {NONE} -- Implementation / Constants

	set_busy_pointer
		do
			set_pointer_style ((create {EV_STOCK_PIXMAPS}).Busy_cursor)
		end

	set_standard_pointer
		do
			set_pointer_style ((create {EV_STOCK_PIXMAPS}).Standard_cursor)
		end

	Window_title: STRING = "Image Eiffel Code"
			-- Title of the window.

	Window_width: INTEGER = 400
			-- Initial width for this window.

	Window_height: INTEGER = 400
			-- Initial height for this window.

	pixmap_window: PICTURE_WINDOW
			-- Window to show the actual pixmap.

	set_change (b: BOOLEAN)
			-- Set `changed' with `b'.
		do
			if b then
				toggle_save
			end
			changed := b
		end

	toggle_save
			-- toggle save button.
		do
			if saved then
				save_button.disable_sensitive
				copy_to_clipboard_button.disable_sensitive
			else
				save_button.enable_sensitive
				copy_to_clipboard_button.enable_sensitive
			end
		end

	build_file (a_pixmap: EV_PIXEL_BUFFER)
			-- Build class file according to `a_pixmap'.
		require
			a_pixmap_attached: a_pixmap /= Void
		local
			i, j: INTEGER
			colors: ARRAYED_LIST [ARRAYED_LIST [NATURAL_32]]
			l_arrayed_list : ARRAYED_LIST [NATURAL_32]
			l_width: INTEGER
			l_iterator: EV_PIXEL_BUFFER_ITERATOR
			l_item: EV_PIXEL_BUFFER_PIXEL
		do
			l_width := a_pixmap.width
			create class_file.make_empty
			create colors.make (a_pixmap.width)
			from
				i := 1
				a_pixmap.lock
				l_iterator := a_pixmap.pixel_iterator
				l_iterator.start
			until
				i > a_pixmap.height

			loop
				create l_arrayed_list.make (l_width)
				colors.extend (l_arrayed_list)
				from
					j := 1
				until
					j > l_width
				loop
					l_item := l_iterator.item
					l_arrayed_list.extend (l_item.rgba_value)
					l_iterator.forth

					j := j + 1
				end
				i := i + 1
			end
			a_pixmap.unlock

			class_file.append (code_producer.build_top_code (class_name))
			class_file.append (code_producer.build_initialization_code (a_pixmap.width, a_pixmap.height))
			class_file.append (code_producer.build_c_external_data_code (a_pixmap))
			class_file.append (code_producer.build_colors_code)
			class_file.append (code_producer.new_line)
			class_file.append (code_producer.build_fill_memory_code (colors, a_pixmap.width, a_pixmap.height))
			class_file.append (code_producer.new_line)
			class_file.append ("end -- " + class_name +"%N")
		end

	class_file: STRING_8
			-- String to contain class text to be generated

	class_name: STRING_32
			-- Name of the class

	file_name: STRING_32
			-- File name of the image

	file_path: STRING_32
			-- File path of the class generated

	default_title: STRING_32
			-- Current window title

	code_producer: CODE_PRODUCER;
			-- Source code generator.

	origin_pixmap: EV_PIXEL_BUFFER;
			-- Original pixmap.

note
	copyright: "Copyright (c) 1984-2012, Eiffel Software"
	license:   "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
	licensing_options: "http://www.eiffel.com/licensing"
	copying: "[
			This file is part of Eiffel Software's Eiffel Development Environment.
			
			Eiffel Software's Eiffel Development Environment is free
			software; you can redistribute it and/or modify it under
			the terms of the GNU General Public License as published
			by the Free Software Foundation, version 2 of the License
			(available at the URL listed under "license" above).
			
			Eiffel Software's Eiffel Development Environment is
			distributed in the hope that it will be useful, but
			WITHOUT ANY WARRANTY; without even the implied warranty
			of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
			See the GNU General Public License for more details.
			
			You should have received a copy of the GNU General Public
			License along with Eiffel Software's Eiffel Development
			Environment; if not, write to the Free Software Foundation,
			Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
		]"
	source: "[
			Eiffel Software
			5949 Hollister Ave., 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 MAIN_WINDOW