implementation module EdTypes

/*	The types for the Editor */

import StdFile
from deltaFont import :: FontName, :: FontSize, :: Font
import UtilDiagnostics
import EdMyIO

//	A strict list data structure

::	List t	=	(:!) infixr 0 !t (List t)
			|	Nil
			
//	The EditWindows: a list of EditWdId's and corresponding EditWindow's
::	EditWindows	:== List (!EditWdId,!EditWindow)			

//	The Defaults: default settings for the EditWindows, Compiler, Code Generator,
//	Application and search paths.

::	Defaults	=	{	defaultCompilerOptions
								:: !CompilerOptions,
						cgo		:: !CodeGenOptions,
						ao		:: !ApplicationOptions,
						po		:: !ProjectOptions,
						paths	:: !List Pathname,
						linkOptions :: !LinkOptions,
						edit	:: !EditWdOptions,
						clip	:: !EditWdOptions,
						errors	:: !EditWdOptions,
						types	:: !EditWdOptions,
						dproject	:: !EditWdOptions }
	// (compiler options,code generator options,application options, project manager options,
	// default search paths, edit/clipboard/errors/types/project window font&size)
	
//	Window position and size

::	LinkOptions = {
		useDefaultSystemObjects :: !Bool,
		useDefaultLibraries :: !Bool,
		extraObjectModules :: !List {#Char},
		libraries :: !List {#Char}
	};

// MW..
::	ABCLinkInfo = {
		linkObjFileNames :: !List LinkObjFileName, // ordered list
		linkLibraryNames :: !List LinkLibraryName  // ordered list
	}

::	ABCLinkPathsCache :== [Pathname]
// ..MW

::	WindowPos_and_Size	= {	posx	:: !Int,
							posy	:: !Int,
							sizex	:: !Int,
							sizey	:: !Int}
	// (position of window, window size)

//	The Editor Options: default settings for the EditWindows.

::	EditOptions	=	{	tabs		:: !Int,
						fontname	:: !FontName,
						fontsize	:: !FontSize,
						autoi		:: !Bool,
						newlines	:: !NewlineConvention};
	// (tabs,font&size,auto indent)

//	The Window parameters: edit options and window position and size
::	EditWdOptions	= {	eo			:: !EditOptions,
						pos_size	:: !WindowPos_and_Size  }
	// edit options, window pos&size
		
//	The Compiler Options: default settings for the compiler.
::	CompilerOptions	=	{	neverMemoryProfile :: !Bool,
							neverTimeProfile	:: !Bool,
							sa		:: !Bool,
							listTypes
									:: !ListTypes,
							attr	:: !Bool,
							gw		:: !Bool,
							bv		:: !Bool,
							gc		:: !Bool,
							reuseUniqueNodes :: !Bool }
	//	(Profile, NotUsed,Types,Show Attributes,Give Warnings,Be Verbose,
	//	Generate Comments)

from UtilNewlinesFile import
	:: NewlineConvention (
	NewlineConventionNone,
	NewlineConventionMac, NewlineConventionUnix, NewlineConventionDos)

//	Compiler options that are stored in the abc file
::	ABCOptions		=	{	abcMemoryProfile 		:: !Bool,
							abcTimeProfile			:: !Bool,
							abcStrictnessAnalysis	:: !Bool,
							abcGiveWarnings			:: !Bool,
							abcBeVerbose			:: !Bool,
							abcGenerateComments		:: !Bool,
							abcReuseUniqueNodes 	:: !Bool };

::	ListTypes	= NoTypes | InferredTypes | StrictExportTypes | AllTypes;
instance == ListTypes
where
	(==) :: ListTypes ListTypes -> Bool
	(==) NoTypes NoTypes
		=	True
	(==) InferredTypes InferredTypes
		=	True
	(==) StrictExportTypes StrictExportTypes
		=	True
	(==) AllTypes AllTypes
		=	True
	(==) _ _
		=	False

instance toString ListTypes
where
	toString :: !ListTypes -> {#Char}
	toString NoTypes
		=	"NoTypes"
	toString InferredTypes
		=	"InferredTypes"
	toString StrictExportTypes
		=	"StrictExportTypes";
	toString AllTypes
		=	"AllTypes"

instance fromString ListTypes
where
	fromString :: {#Char} -> ListTypes
	fromString "NoTypes"
		=	NoTypes
	fromString "InferredTypes"
		=	 InferredTypes
	fromString "StrictExportTypes"
		=	StrictExportTypes
	fromString "AllTypes"
		=	AllTypes
	fromString _
		=	Unexpected "fromString (Types): unknown Type" NoTypes

//	The Code Generator Options: default settings for the code generator
::	CodeGenOptions	=	{	cs	:: !Bool,
							ci	:: !Bool,
							kaf	:: !Bool,
							tp	:: !Processor }

::	Processor = CurrentProcessor | MC68000 | MC68020 | MC68020_and_68881

instance == Processor
where
	(==) :: Processor Processor -> Bool
	(==) CurrentProcessor CurrentProcessor
		=	True
	(==) MC68000 MC68000
		=	True
	(==) MC68020 MC68020
		=	True
	(==) MC68020_and_68881 MC68020_and_68881
		=	True
	(==) _ _
		=	False

UnexpectedConstructor :: {#Char} {#Char} .a -> .a
UnexpectedConstructor typeName string defaultValue
	=	Unexpected ( "fromString (" +++ typeName +++ "): unknown value (" +++ string +++ ")\n") defaultValue

instance fromString Processor
where
	fromString :: {#Char} -> Processor
	fromString "CurrentProcessor"
		=	CurrentProcessor
	fromString "MC68000"
		=	MC68000
	fromString "MC68020"
		=	MC68020
	fromString "MC68020_and_68881"
		=	MC68020_and_68881
	fromString string
		=	UnexpectedConstructor "Processor" string CurrentProcessor

instance toString Processor
where
	toString :: Processor -> {#Char}
	toString MC68000
		=	"MC68000"
	toString MC68020
		=	"MC68020"
	toString MC68020_and_68881
		=	"MC68020_and_68881"
	toString CurrentProcessor
		=	"CurrentProcessor"

// (Check Stacks, Check Indices, Keep ABC files, Target Processor)

//	The Application Options: default settings for the application.
::	ApplicationOptions	=	{	hs	:: !Int,
								ss	:: !Int,
								em	:: !Int,
				heap_size_multiple	:: !Int,
				initial_heap_size	:: !Int,
								set	:: !Bool,
								sgc	:: !Bool,
								pss	:: !Bool,
				marking_collection	:: !Bool,
								o	:: !Output,
								fn	:: !FontName,
								fs	:: !FontSize ,
					write_stderr_to_file
									:: !Bool,
					memoryProfiling :: !Bool,
					memoryProfilingMinimumHeapSize :: !Int,

					   profiling601 :: !Bool, // RWS: temporary
						  profiling :: !Bool }

::	Output = BasicValuesOnly | ShowConstructors | NoConsole

instance == Output
where
	(==) :: Output Output -> Bool
	(==) BasicValuesOnly BasicValuesOnly
		=	True
	(==) ShowConstructors ShowConstructors
		=	True
	(==) NoConsole NoConsole
		=	True
	(==) _ _
		=	False;

instance fromString Output
where
	fromString :: {#Char} -> Output
	fromString "BasicValuesOnly"
		=	BasicValuesOnly
	fromString "ShowConstructors"
		=	ShowConstructors
	fromString "NoConsole"
		=	NoConsole
	fromString string
		=	UnexpectedConstructor "Output" string BasicValuesOnly

instance toString Output
where
	toString :: Output -> {#Char}
	toString BasicValuesOnly
		=	"BasicValuesOnly"
	toString ShowConstructors
		=	"ShowConstructors"
	toString NoConsole
		=	"NoConsole"


	// Heap Size, Stack Size, Extra Memory,Show Execution Time,Show Garbage
	//		Collections, Print Stack Size,Output,Font Name,Font Size

//	The Project Manager Options: default settings for the project manager.
::	ProjectOptions		=	{	verbose	:: !Bool  };
	//	be verbose

//	The Clipboard: a portion of text copied or cut from an EditWindow

::	Clipboard	:== List String;

//	FindInfo: what has been entered in the Find dialog?

::	FindInfo	=	{	find	:: !String,
						replace	:: !String,
						ignore	:: !Bool,
						backw	:: !Bool,
						wrapa	:: !Bool,
						matchw	:: !Bool  };
	//	(Find, Replace, Ignore case, Backwards, Wrap around, Match words)

// FindIdentInfo: What has been entered in the Find Identifier dialog?
	
::	FindIdentInfo	=	{
		search_kind :: !SearchKind,
		cleanid	:: !String,
		imp		:: !SearchType,
		export_	:: !Bool,
		verbose	:: !Bool
	 };

::	SearchKind = Definition | Implementation | Identifier;
::	SearchType	= SearchPaths | SearchImports;
instance == SearchType
where
	(==) :: SearchType SearchType -> Bool;
	(==) SearchPaths SearchPaths
		=	True;
	(==) SearchImports SearchImports
		=	True;
	(==) _ _
		=	False;

// ErrorLineNr: The current line number in the Error window.

::	ErrorLineNr :== Int;

//	The EditWdIds: to be able to generate a new unique window-id

::	EditWdIds	=	{	wdids	:: !List EditWdId,
						curid	:: !EditWdId  };
::	EditWdId	:== Int;

::	Text		:== List Block;
::	Block		:== List TLine;
::	TLine		:== List String;

::	UndoInfo	=	{	clipcopied	:: !ClipCopied,
						removed		:: !Removed,
						added		:: !PartTSel,
						replaced	:: !ReplacedAll,
						menu		:: !UndoMenuItem  };
	// text copied to clipboard, removed text, added text (first linenr&charnr, last line&charnr),
	// replaced all undo info,menu status
	
::	ClipCopied	=	{	clipset		:: !Bool,
						clipboard	:: !Clipboard,
						pos			:: !PartTSel  };
	// clipboard copied?, contents, coordinates
						
::	Removed		=	{	before		:: !List String,
						after		:: !List String,
						lnr			:: !Int,
						cnr			:: !Int  };
	// removed part before cursor, removed part behind cursor (reversed), insertion point

::	ReplacedAll	=	{	len		:: !Int,
						org		:: !String,
						repl	:: !String,
						ln_cns	:: !List Replaced  };
	// length of the piece of text to be replaced, original string, replacement string, line&char
	// numbers of replace positions.
	
::	Replaced	=	{	lnr		:: !Int,
						cnr		:: !Int  };
	// line&char numbers of replace position.
	
::	UndoMenuItem = 	{	undo	:: !Bool,
						action	:: !String  };
	// undo/redo, name of action to be undone/redone.
	
::	CursorPos	=	{	vis		:: !Bool,
						x		:: !Int,
						y		:: !Int,
						u_d		:: !Int  };
	//	Is it visible, pos in pixels, for U&D
	
::	CurLine		=	{	changed	:: !Bool,
						before	:: !TLine,
						after	:: !TLine,
						lnr		:: !Int,
						cnr		:: !Int  };
	//	(current line changed, before cursor, after cursor, linenr, cursorpos (charnr))
	
::	Selection	=	{	tsel	:: !PartTSel,
						psel	:: !PartPSel  };
	// text selection, pixel selection

::	PartTSel	=	{	l1		:: !Int,
						c1		:: !Int,
						l2		:: !Int,
						c2		:: !Int  };
	// (Linenr, Charnr, Linenr, Charnr)
	
::	PartPSel	= 	{	bx		:: !Int,
						by		:: !Int,
						ex		:: !Int,
						ey		:: !Int  };
	// (beginx,beginy,endx,endy)
	
::	ActPasPos	=	{	lnr		:: !Int,
						cnr		:: !Int,
						x		:: !Int,
						y		:: !Int  };
	
::	TabWidth	=	{	ttabw	:: !Int,
						ptabw	:: !Int  };
	// (tabwidth, tabwidth in pixels)

::	WindowFont	= 	{	fontname	:: !FontName,
						fontsize	:: !FontSize,
						font		:: !Font  };

::	FontMetr	=	{	ascent	:: !Int,
						descent	:: !Int,
						lead	:: !Int,
						height	:: !Int  };
	// (Ascent, Descent, Leading, Height)
				
::	NrLines				:== Int;
::	Saved				:== Bool;
::	AutoIndent			:== Bool;
::	NrLines_and_Text	:== (!NrLines, !Text);

::	ExecWdId			:==	EditWdId;

/* modifiers for the DirectionKey function. */
::	KeyMode =	None | Optn | Comd
instance == KeyMode
where
	(==) :: KeyMode KeyMode -> Bool
	(==) None None
		=	True
	(==) Optn Optn
		=	True
	(==) Comd Comd
		=	True
	(==) _ _
		=	False

/* Scroll modes */
:: ScrollMode	= ScrollLine | ScrollHalfWin | ScrollFullWin | ScrollNone;
instance == ScrollMode
where
	(==) :: ScrollMode ScrollMode -> Bool;
	(==) ScrollLine ScrollLine
		=	True;
	(==) ScrollHalfWin ScrollHalfWin
		=	True;
	(==) ScrollFullWin ScrollFullWin
		=	True;
	(==) ScrollNone ScrollNone
		=	True;
	(==) _ _
		=	False;

::	WdType = EditWd | ErrorWd | TypeWd | ProjectWd | ClpbrdWd;
instance == WdType
where
	(==) :: WdType WdType -> Bool;
	(==) EditWd EditWd
		=	True;
	(==) ErrorWd ErrorWd
		=	True;
	(==) TypeWd TypeWd
		=	True;
	(==) ProjectWd ProjectWd
		=	True;
	(==) ClpbrdWd ClpbrdWd
		=	True;
	(==) _ _
		=	False;

// Window and line update info
::	WindowUpdate =	{	added				:: !PartTSel,
						nrremoved			:: !NrLines, 
						removed				:: !Clipboard,
						oldsel				:: !Selection,
						selection			:: !Selection,
						oldpos				:: !CursorPos,
						curpos				:: !CursorPos  };
						
	// text added (text selection), nr of lines removed, text removed, old and new selection,
	// old and new cursor position.
	
	// Note:	If a change only effects one line, i.e. the new current line, the text it self is
	//			not changed, only the new current line is.
	//			So before an operation effecting more than one line is performed changes to the
	//			current line are made permanent in the text. 

::	LineUpdate	=	{	oldpos			:: !CursorPos,
						newpos			:: !CursorPos,
						width			:: !Int  };
	// old/new cursor position, width of the text removed
	
//	Windows

::	EditWindow
	= {	wstate		:: !WinState,
		wtext		:: !WinText,
		wformat		:: !WinFormat  };
	
::	WinState
	= {	saved		:: !Saved,
		undoinfo	:: !UndoInfo,
		wdtype		:: !WdType,
		pathname	:: !Pathname,
		co			:: !CompilerOptions  };

::	WinText
	= {	text		:: !Text,
		nrlines		:: !NrLines,
		cursorpos	:: !CursorPos,
		curline		:: !CurLine,
		selection	:: !Selection  };
		
::	WinFormat
	= {	tabw		:: !TabWidth,
		autoi		:: !AutoIndent,
		newlines	:: !NewlineConvention,
		winfont		:: !WindowFont,
		metrics		:: !FontMetr  };

// The Project
::	Modulename		:== String;
::	Pathname		:== String;
::	LinkObjFileName	:==	String;	// MW++
::	LinkLibraryName	:==	String;	// MW++
::	Filename		:== String;	// MW++

::	ModInfo		=	{	dir				:: !Pathname,
						compilerOptions	:: !CompilerOptions,
						defeo 			:: !EditWdOptions,
						impeo			:: !EditWdOptions,
						defopen 		:: !Bool,
						impopen 		:: !Bool,
						date 			:: !DATE,
						deps 			:: !List Modulename,
						abcLinkInfo 	:: ABCLinkInfo	// MW++
						};
	// directory, compiler options, edit options, win pos & win size of .dcl/.icl file,
	// .dcl window open?, .icl window open?, last scan date of file, modules imported.

::	CodeGenerateAsmOrCode	= AsmGeneration | CodeGeneration;
instance == CodeGenerateAsmOrCode
where
	(==) :: CodeGenerateAsmOrCode CodeGenerateAsmOrCode -> Bool;
	(==) AsmGeneration AsmGeneration
		=	True;
	(==) CodeGeneration CodeGeneration
		=	True;
	(==) _ _
		=	False;

::	CompileOrCheckSyntax	= SyntaxCheck | Compilation;
instance == CompileOrCheckSyntax
where
	(==) :: CompileOrCheckSyntax CompileOrCheckSyntax -> Bool;
	(==) SyntaxCheck SyntaxCheck
		=	True;
	(==) Compilation Compilation
		=	True;
	(==) _ _
		=	False;

::	CompileClearCache	= ClearCache | Don`tClearCache;
instance == CompileClearCache
where
	(==) :: CompileClearCache CompileClearCache -> Bool;
	(==) ClearCache ClearCache
		=	True;
	(==) Don`tClearCache Don`tClearCache
		=	True;
	(==) _ _
		=	False;
