module edit #+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

	import gui from gui_win32.ala #!!!!!!!!!!!!!!!!!!!!!!!!!
	
	
	#Edit classes +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	class EditOp
		opCode=0
		str letter
		all variable
		row=0 #cursor row before op
		col=0
		firstVisibleRow=0
		selRow=0
		selCol=0
	
		auxCol=0
		auxRow=0
	
		#all undoOp
	
	class Edit
		Control control
		StrTable text
		cursorRow=0
		cursorCol=0
	
		firstVisibleRow=0
	
		viewX=0
		lineH=20
		leftMargin=10
		tabLength=64#8*8 72 #8*9
		font=0
	
		selLastRow=-1;selEndCol=-1 #end included in selection
	
		horScrollRange=0
	
		Fifo undo 
		Fifo redo

		File file  

		hdc=0  
		cursorH=0
		shiftPressed=0
		ctrlPressed=0
		mouseLBD=0
		
	
	#Edit classes end ==============================================================


	
	#Edit consts ++++++++++++++++++++++++++++++
	const EDIT_UPPER_MARGIN 10
	const EDIT_STATE_APPEND	0
	const EDIT_STATE_INSERT	1
	
	const EDIT_OP_INSERT_CHAR 1
	const EDIT_OP_DELETE_CHAR 2
	const EDIT_OP_DELETE_CHAR_1 3
	
	const EDIT_OP_INSERT_PARAGRAPH 4
	const EDIT_OP_DELETE_PARAGRAPH 5
	const EDIT_OP_DELETE_PARAGRAPH_1 6
	const EDIT_OP_DELETE_SELECTION 7
	const EDIT_OP_INSERT_TEXT 8
	const EDIT_OP_INSERT_LINES 9
	
	
	#Edit consts end =================================================

	
	
	#Edit start ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	Edit Edit(int x,int y, int w, int h,int font,Window parent)= #*********************************
		null=0; Edit edit;style=0
	
		style=setBit(style,0) 	#has hor scroll
	
		style=setBit(style,1)	#has ver scroll
	
		edit.control=Control(x,y,w,h,style,"",parent.id)
	
		edit.text=StrTable() #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

		$if os mswindows #>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
		bind edit.control,WM_PAINT,eventDraw(edit)#draw(edit) 
	
		bind edit.control, WM_KEYDOWN, keyPressedWin32(edit,systemEvent)

		bind edit.control, WM_KEYUP, keyUpWin32(edit,systemEvent)

	
		bind edit.control, MOUSE_LBD, mouseLBD(edit, systemEvent) 
		bind edit.control, MOUSE_LBU, mouseLBU(edit, systemEvent)
		bind edit.control, MOUSE_MOVE, mouseMove(edit, systemEvent)

		bind edit.control, WM_VSCROLL, verScroll(edit, systemEvent)

		bind edit.control, WM_HSCROLL, horScroll(edit, systemEvent)

	
		edit.undo=Fifo(100)
		edit.redo=Fifo(100)
	
	
		client_rect=getClientRect(edit.control)
		edit.horScrollRange=client_rect.w+client_rect.w/2

		edit.cursorH=edit.lineH-3
		edit.font=font 

		edit.hdc=getDC(edit.control.id) 

		call gdi32.SelectObject(edit.hdc,edit.font)

		return edit

	proc destructor(Edit edit)
		releaseDC(edit.control.id,edit.hdc)

	proc setVerScrollRange(Edit edit)
		lines=len(edit.text)

		client_rect=getClientRect(edit.control)
		view_lines=client_rect.h/edit.lineH

		updateVerScroll(edit.firstVisibleRow,view_lines,lines,edit.control)

	
	proc eventDraw(Edit edit)=
		PAINTSTRUCT ps; hdc=0

		oldHdc=edit.hdc
		call user32.BeginPaint(edit.control.id,ps); mov hdc,eax

		
		edit.hdc=hdc

		call gdi32.SelectObject(hdc,edit.font)

		draw(edit)

		call user32.EndPaint(edit.control.id,ps)
		edit.hdc=oldHdc

	
		
	
	proc draw(Edit edit)=#*******************************************
		
		text_rect=getClientRect(edit.control) 
	
		drawText(edit,text_rect) #!!!!!!!!!!!!!!!!!
	
	
	proc drawText(Edit edit, Rect rect)= #*************************************************
		text="";c=""
	
		#draw background
		color=WHITE

		drawRect(edit.hdc,rect,color)

		lineIndex=edit.firstVisibleRow 
	
		cliRe=getClientRect(edit.control)
	
	
		viewH=edit.lineH;y0t=cliRe.y+1
		lenT=len(edit.text)
	
		controlViewH=cliRe.h#!!!!!!!!!!
	
		et1:#-------------------------
		if lineIndex < lenT and viewH < controlViewH
			withBackground=0
			drawTextLine(edit,lineIndex,withBackground,rect) #!!!!!!!!!!!!
	
			viewH=viewH+edit.lineH
			lineIndex=lineIndex+1 
			goto et1#-------------------------
	
	int tabPosition(Edit edit, int x)=
		res=0
		x_ala=x+edit.viewX
	
		tab_no=(x_ala-edit.leftMargin)/edit.tabLength+1
		
		res=tab_no*edit.tabLength +edit.leftMargin-edit.viewX
	
		return res



	int drawStr(Edit edit,str text,int x ,int y,int color, Rect inRect)=
		xt=x
		le_text=len(text);to_draw=""

		drawRect=Rect(x,y,MAX_RES_X,MAX_RES_Y)
		for ind=0 to le_text-1
			char_to_draw=text[ind] 
			
			if ord(char_to_draw)=9 # tab code
				if to_draw
					drawRectHere=andRects(drawRect,inRect)
					xt=drawCharA(edit.hdc,drawRectHere,char_to_draw,color)

					to_draw=""
				xt=tabPosition(edit,xt)
					
			else
				to_draw=to_draw+char_to_draw
			
		if to_draw
			drawRectHere=andRects(drawRect,inRect)

			xt=drawStrA(edit.hdc,drawRectHere,to_draw,color)
	
		return xt	



	
	int findTextEnd(Edit edit,str text,int x )=
		xt=x
		le_text=len(text);to_draw=""
		for ind=0 to le_text-1
			char_to_draw=text[ind] 
			
			if ord(char_to_draw)=9 # tab code
				if to_draw
					xt=xt+getTextWidth(edit.hdc,to_draw)
					to_draw=""
				xt=tabPosition(edit,xt)
					
			else
				to_draw=to_draw+char_to_draw
			
		if to_draw
			xt=xt+getTextWidth(edit.hdc,to_draw)
	
		return xt

	int drawStr(Edit edit,str text, int x, int y,int color,int backColor,int backDY,int backH,Rect rect)=
	
		textWidth=findTextEnd(edit,text,x)-x
		yBack=y-backDY
	
		drawRect=Rect(x,yBack,textWidth,backH)
		drawRect=andRects(drawRect,rect)
		drawRect(edit.hdc,drawRect,backColor)
	
		xt=drawStr(edit,text,x , y,color, rect)
		return xt
	
	proc drawTextLine(Edit edit,int lineIndex)=#***********************************************************
		re=getClientRect(edit.control);withBackground=1
		drawTextLine(edit,lineIndex,withBackground,re)


	proc drawTextLine(Edit edit,int lineIndex,int withBackground,Rect inRect)= #***********************************
		auxText="";c="";textSel=""

		setBkMode(edit.hdc,TRANSPARENT)	#mode TRANSPARENT when old background is left and OPAQUE
	
		lineOff=lineIndex-edit.firstVisibleRow #!!!!!!!!!
		if lineOff >=0
			re=getClientRect(edit.control)
	
			xt=re.x+edit.leftMargin-edit.viewX
			
			y0=re.y#!!!!!!!!
			yr=y0+lineOff*edit.lineH+EDIT_UPPER_MARGIN
			re.y=yr;re.h=edit.lineH#!!!!!!!!!!!!
	
			yre=yr+edit.lineH;yt=yr #!!!!!!!!!!!!!
	
			yEnd=re.y+re.h
			if yre<=yEnd
				re.y=yr;re.h=edit.lineH
				if withBackground
					#draw background
					color=WHITE
					
					drawRect=andRects(re,inRect)
					drawRect(edit.hdc,drawRect,color)
	
				textLine=edit.text[lineIndex]#!!!!!!!!!!!!!!
				color=BLACK
	
				no_selection=1
				if edit.selLastRow >=0
					
					if edit.selLastRow = edit.cursorRow
						if lineIndex=edit.cursorRow :no_selection=0
	
					elif edit.selLastRow > edit.cursorRow
						if lineIndex >= edit.cursorRow and lineIndex <= edit.selLastRow : no_selection=0
	
					else
						if lineIndex >= edit.selLastRow and lineIndex <= edit.cursorRow : no_selection=0

				if no_selection # so selection
			
					if lineIndex=edit.cursorRow #with cursor
						le=len(textLine)
						cursorY=yt #+2
			
						if edit.cursorCol>=le #cursor at the end of line
	
							xs=drawStr(edit,textLine.s,xt , yt,color, inRect)#!!!!!!!!!!!!!!!!
							xs=xs+1;drawCursor(edit.hdc,xs,cursorY,edit.cursorH,inRect) #draw cursor !!!!!!!!!!!!!!!!!!
							xt=xs
						else
							if edit.cursorCol >0
								auxText=textLine[0:edit.cursorCol]
								xt=drawStr(edit,auxText,xt , yt,color, inRect)#!!!!!!!!!!!!!!!!
							if xt !=AFTER_RECT
								cursorX=xt 
								auxText=textLine[edit.cursorCol:]
								xt=drawStr(edit,auxText,xt , yt,color, inRect)#!!!!!!!!!!!!!!!!
					
								drawCursor(edit.hdc,cursorX,cursorY,edit.cursorH,inRect) #draw cursor !!!!!!!!!!!!!!!!!!
					else
						xt=drawStr(edit,textLine.s,xt , yt,color,inRect)
			
				else # with selection++++++++++++++++++++++++++++++++++
					
					if edit.selLastRow = edit.cursorRow
						selBeginRow=edit.cursorRow
						selLastRow=selBeginRow
						if edit.selEndCol > edit.cursorCol
							selBeginCol=edit.cursorCol;selEndCol=edit.selEndCol
						else
							selBeginCol=edit.selEndCol;selEndCol=edit.cursorCol
	
					elif edit.selLastRow >edit.cursorRow
						selBeginRow=edit.cursorRow;selBeginCol=edit.cursorCol
						selLastRow=edit.selLastRow;selEndCol=edit.selEndCol
					else
						selBeginRow=edit.selLastRow;selBeginCol=edit.selEndCol
						selLastRow=edit.cursorRow;selEndCol=edit.cursorCol
	
	
					colorSel=WHITE;selBackColor=BLUE
					
					ySelDelta=3;hSel=edit.lineH#!!!!!!!!!!!!
	
					if lineIndex=selBeginRow and lineIndex=selLastRow
						auxText=textLine[0:selBeginCol]
						xt=drawStr(edit,auxText,xt , yt,color, inRect)#draw not selected!!!!!!!!!!!!!!!!
	
						if xt !=AFTER_RECT
							auxText=textLine[selBeginCol:selEndCol]
							xt=drawStr(edit,auxText,xt , yt,colorSel, selBackColor,ySelDelta,hSel,inRect)#draw selected!!!!!!!!!!!!!!!!
							if xt !=AFTER_RECT
								auxText=textLine[selEndCol:]
								xt=drawStr(edit,auxText,xt , yt,color, inRect)#draw not selected!!!!!!!!!!!!!!!!
	
	
					elif lineIndex=selBeginRow
						auxText=textLine[0:selBeginCol]
						xt=drawStr(edit,auxText,xt , yt,color, inRect)#draw not selected!!!!!!!!!!!!!!!!
						
						if xt !=AFTER_RECT
							auxText=textLine[selBeginCol:]
							xt=drawStr(edit,auxText,xt , yt,colorSel, selBackColor,ySelDelta,hSel,inRect)#draw selected!!!!!!!!!!!!!!!!
		
		
					elif lineIndex=selLastRow
						#endSelCol=edit.cursorCol+1
						auxText=textLine[:selEndCol]
						xt=drawStr(edit,auxText,xt , yt,colorSel, selBackColor,ySelDelta,hSel,inRect)#draw selected!!!!!!!!!!!!!!!!
	
						if xt !=AFTER_RECT
							auxText=textLine[selEndCol:]
							xt=drawStr(edit,auxText,xt , yt,color, inRect)#draw not selected!!!!!!!!!!!!!!!!
		
					else
						xt=drawStr(edit,textLine.s,xt , yt,colorSel, selBackColor,ySelDelta,hSel,inRect)#draw selected!!!!!!!!!
		end:#===========

	proc clearTextLine(Edit edit,int lineIndex)= #***********************************
		re=getClientRect(edit.control)
		auxText="";c="";textSel=""
	
		lineOff=lineIndex-edit.firstVisibleRow #!!!!!!!!!
		if lineOff >=0
			re=getClientRect(edit.control)
			xt=re.x+edit.leftMargin-edit.viewX
			
			y0=re.y#!!!!!!!!
			yr=y0+lineOff*edit.lineH+EDIT_UPPER_MARGIN

			re.y=yr;re.h=edit.lineH#!!!!!!!!!!!!
	
			yre=yr+edit.lineH;yt=yre#-3 #!!!!!!!!!!!!!
	
			yEnd=re.y+re.h
			if yre<=yEnd
				re.y=yr;re.h=edit.lineH
	
				#draw background
				color=WHITE

				drawRect(edit.control.parentId,re,color) 

	#------------------------------------------------------------
	
	proc writeUndo(Edit edit,int opCode,str key)=#****************************************************
		EditOp edit_op; edit_op.opCode=opCode
		edit_op.row=edit.cursorRow;edit_op.col=edit.cursorCol;edit_op.firstVisibleRow=edit.firstVisibleRow
		edit_op.letter=key; append(edit.undo,edit_op)
	
	proc writeUndo(Edit edit,int opCode,int var )=#*****************************************************
		EditOp edit_op; edit_op.opCode=opCode
		edit_op.row=edit.cursorRow;edit_op.col=edit.cursorCol;edit_op.firstVisibleRow=edit.firstVisibleRow
		edit_op.variable=var; append(edit.undo,edit_op)
	
	proc writeUndo(Edit edit,int opCode,list var,int row, int col)=#*****************************************************
		EditOp edit_op; edit_op.opCode=opCode
		edit_op.row=edit.cursorRow;edit_op.col=edit.cursorCol;edit_op.firstVisibleRow=edit.firstVisibleRow
		edit_op.selRow=edit.selLastRow; edit_op.selCol=edit.selEndCol
		edit_op.variable=var; edit_op.auxRow=row; edit_op.auxCol=col;append(edit.undo,edit_op)
	
	
	proc writeUndo(Edit edit,int opCode,int row, int col)=#*****************************************************
		EditOp edit_op; edit_op.opCode=opCode
		edit_op.row=edit.cursorRow;edit_op.col=edit.cursorCol;edit_op.firstVisibleRow=edit.firstVisibleRow
		edit_op.selRow=edit.selLastRow; edit_op.selCol=edit.selEndCol
		edit_op.auxRow=row; edit_op.auxCol=col;append(edit.undo,edit_op)

	#---------------------------------------------------------

	proc keyPressed(Edit edit, int keyCode)= #**********************************
		key=chr(keyCode)
	
		writeUndo(edit,EDIT_OP_INSERT_CHAR,key) #!!!!!!!!!!!!!
	
		text=""
		leET=len(edit.text)
		if leET=0
			new=append(edit.text,key)
			edit.cursorCol=1
	
		elif edit.cursorRow= 65 and keyCode <= 90 #letter from A to Z
			if edit.shiftPressed=0 :keyCode=keyCode+32 # change A -> a

			et1:#--------------------------

			key=chr(keyCode)

		
			writeUndo(edit,EDIT_OP_INSERT_CHAR,key) #!!!!!!!!!!!!!
		
			text=""
			leET=len(edit.text)
			if leET=0
				new=append(edit.text,key)
				edit.cursorCol=1
		
			elif edit.cursorRow=48 and keyCode <=57 # 0 to 9
			if edit.shiftPressed
				if keyCode=48 :keyPressed=33
				elif keyCode=49:keyPressed=64
				elif keyCode=50:keyPressed=35
				elif keyCode=51:keyPressed=36
				elif keyCode=52:keyPressed=37
				elif keyCode=53:keyPressed=94
				elif keyCode=54:keyPressed=38
				elif keyCode=55:keyPressed=42
				elif keyCode=56:keyPressed=40
				elif keyCode=57:keyPressed=41
			goto et1#------------------------

		elif keyCode=219
			if edit.shiftPressed: keyCode=123
			else: keyCode=91
			goto et1#--------------------

		elif keyCode=221
			if edit.shiftPressed: keyCode=125
			else: keyCode=93
			goto et1#--------------------

		elif keyCode=222
			if edit.shiftPressed: keyCode=34
			else: keyCode=39
			goto et1#--------------------

		elif keyCode=186
			if edit.shiftPressed: keyCode=58
			else: keyCode=59
			goto et1#--------------------


		elif keyCode=220
			if edit.shiftPressed: keyCode=124
			else: keyCode=92
			goto et1#--------------------

		elif keyCode=188
			if edit.shiftPressed: keyCode=60
			else: keyCode=44
			goto et1#--------------------

		elif keyCode=191
			if edit.shiftPressed: keyCode=63
			else: keyCode=47
			goto et1#--------------------

		elif keyCode=190
			if edit.shiftPressed: keyCode=62
			else: keyCode=46
			goto et1#--------------------

		elif keyCode=192
			if edit.shiftPressed: keyCode=126
			else: keyCode=39
			goto et1#--------------------

		elif keyCode=189
			if edit.shiftPressed: keyCode=95
			else: keyCode=45
			goto et1#--------------------

		elif keyCode=187
			if edit.shiftPressed: keyCode=43
			else: keyCode=61
			goto et1#--------------------

		elif keyCode >= 32 and keyCode <127 #ascii char

			goto et1#-----------------------------

			

	proc keyUpWin32(Edit edit, Event event)= #**********************************

		keyCode=event.wParam
		if keyCode=KEY_SHIFT: edit.shiftPressed=0
		elif keyCode=KEY_CTRL: edit.ctrlPressed=0

	

	proc keyEnter(Edit edit)= #******************************************************
	
		writeUndo(edit,EDIT_OP_INSERT_PARAGRAPH,"") #!!!!!!!!!!!!!
	
		Rect move_rect
		cursor_row=edit.cursorRow; new_cursor_row=cursor_row+1
		text1="";scroll=0
		lines=len(edit.text); last_row=lines-1
		text=edit.text[cursor_row] 
		le=len(text)
		client_rect=getClientRect(edit.control)
	
		if edit.cursorCol >=le-1 #last char
			
			if edit.cursorRow >=lines-1 #last line
				ns=append(edit.text,text1)
			else
				insert(edit.text,new_cursor_row,text1)
		else
			curr_line=edit.text[cursor_row] 
			text1=curr_line.s[0:edit.cursorCol]
			text2=curr_line.s[edit.cursorCol:]
			curr_line.s=text1
		
			if cursor_row < last_row
	
				insert(edit.text,new_cursor_row,text2)
			else
				ns=append(edit.text,text2)
	
	
		view_lines=client_rect.h/edit.lineH
	
		last_visible=edit.firstVisibleRow+view_lines-1 
	
		if cursor_row =last_row or cursor_row=last_visible#last row
			if cursor_row+1>last_visible
				edit.firstVisibleRow=edit.firstVisibleRow+1
	
				x=client_rect.x;y=client_rect.y
				setXYWH(move_rect,x,y+edit.lineH,client_rect.w,(view_lines-2)*edit.lineH)
				moveRect(edit.hdc,x,y,move_rect)
	
			edit.cursorCol=0
			edit.cursorRow=edit.cursorRow+1
				
			drawTextLine(edit,cursor_row)#draw old without cursor
			drawTextLine(edit,edit.cursorRow)#draw new with cursor
	
				
		else # not last row
			curr_off=cursor_row-edit.firstVisibleRow
			x=client_rect.x; y=client_rect.y+(curr_off+1)*edit.lineH
	
			if lines< view_lines
				h=(lines-curr_off-1)*edit.lineH 
	
			else
				h=(view_lines-curr_off-2)*edit.lineH 
	
			setXYWH(move_rect,x,y,client_rect.w,h)
			moveRect(edit.hdc,x,y+edit.lineH,move_rect)
	
			edit.cursorCol=0
			edit.cursorRow=edit.cursorRow+1
				
			drawTextLine(edit,cursor_row)#draw old without cursor
			drawTextLine(edit,edit.cursorRow)#draw new with cursor
		drawControl(edit.control) 

	proc keyBackspace(Edit edit)= #***********************************
	
		if edit.cursorCol>0
			#delete char
	
			text=edit.text[edit.cursorRow] 
	
			deleted=text.s[edit.cursorCol-1]
	
			writeUndo(edit,EDIT_OP_DELETE_CHAR,deleted) #!!!!!!!!!!!!!
	
			delete(text.s,edit.cursorCol-1)  
	
			edit.cursorCol=edit.cursorCol-1  
	
			drawTextLine(edit,edit.cursorRow)
	
			
		elif edit.cursorRow >0
	
			old_cursor_row=edit.cursorRow
			deleted_line=edit.text[edit.cursorRow] 
	
			delete(edit.text,old_cursor_row)
	
			new_cursor_row=edit.cursorRow-1
			
			line=edit.text[new_cursor_row]
			new_col=len(line.s)
			writeUndo(edit,EDIT_OP_DELETE_PARAGRAPH,new_col) #!!!!!!!!!!!!!
	
			if len(deleted_line.s) >0
				line.s=line.s+deleted_line.s
	
			edit.cursorRow=new_cursor_row
			edit.cursorCol=new_col
	
	
			if old_cursor_row > edit.firstVisibleRow
		
				moveUp(edit,edit.cursorRow+2)
		
			drawTextLine(edit,edit.cursorRow) #draw new with cursor
		drawControl(edit.control) 

	
	
	proc keyDelete(Edit edit)= #**************************
	
		if edit.selLastRow=-1 # no selection
		
			text=edit.text[edit.cursorRow] 
			le=len(text)
			if le >0
				if edit.cursorCol0
	
			move_rect.x=client_rect.x;move_rect.w=client_rect.w
		
			move_rect.y=client_rect.y+offset*lineH
		
			move_rect.h=row_count*lineH
		
			new_y=move_rect.y-lineH
			
			moveRect(edit.hdc,client_rect.x,new_y,move_rect)
		
		last_visible=edit.firstVisibleRow+visible_lines-1
	
		if visible_lines=view_lines
	
			drawTextLine(edit,last_visible)
		else
			new_y=client_rect.y+(last_visible+1)*lineH

			drawRect(edit.control.parentId,client_rect.x,new_y,client_rect.w,lineH,WHITE) #clear last row

	
	proc clearSelection(Edit edit)=
		
		if edit.selLastRow >= edit.cursorRow
			start=edit.cursorRow; end=edit.selLastRow
		else
			start=edit.selLastRow; end=edit.cursorRow
	
		edit.selLastRow=-1;edit.selEndCol=-1
	
		for ind=start to end
			drawTextLine(edit,ind)
	
	
	
	proc keyArrowLeft(Edit edit)=
		if edit.cursorCol>0
			edit.cursorCol=edit.cursorCol-1;drawTextLine(edit,edit.cursorRow)
		clearSelection(edit)
		drawControl(edit.control) 

	
	proc keyArrowRight(Edit edit)=
		text=edit.text[edit.cursorRow] 
		le=len(text)
		if edit.cursorCol0
			changeCursorRow(edit,-1) #!!!!!!!!!!!!!!
	
	
			if edit.cursorRow0		#!!!!!!!!!!!!
	
			scrollLineUp(edit,1,0)#!!!!!!!!!!!!!!!!!!
		
			drawTextLine(edit,edit.firstVisibleRow)#draw first!!!!!!!!
	
	proc scrollLineUp(Edit edit, int skip_rows_count, int first_row)= #move down
		Rect move_rect;delta=0
	
		if first_row
			delta=edit.lineH*first_row;delta_ala=delta
		else:delta_ala=edit.lineH
	
		lines=len(edit.text)
		client_rect=getClientRect(edit.control)
		view_lines=client_rect.h/edit.lineH
		visible_lines=min(lines-edit.firstVisibleRow,view_lines)
	
		move_rect.x=client_rect.x;move_rect.w=client_rect.w
		move_rect.y=client_rect.y+delta
	
		if visible_lines > skip_rows_count
			move_rect.h=(visible_lines-skip_rows_count)*edit.lineH
			new_y=move_rect.y+delta_ala
			moveRect(edit.hdc,client_rect.x,new_y,move_rect)
	
		edit.firstVisibleRow=edit.firstVisibleRow-1 #!!!!!!!!!!
	
		updateVerScroll(edit.firstVisibleRow,view_lines,lines,edit.control)#!!!!!!!!!!!!!!!
		
	proc keyArrowDown(Edit edit)=
		
		oldcursorRow=edit.cursorRow#!!!!!!!!!
		leText=len(edit.text)
		if edit.cursorRowlast_line
				scrollLineDown(edit,client_rect,view_lines-2)#!!!!!!!!!!!!!!!!!!
		
			drawTextLine(edit,oldcursorRow)#!!!!!!!!
			drawTextLine(edit,edit.cursorRow)#!!!!!!!!
	
			updateVerScroll(edit.firstVisibleRow,view_lines,leText,edit.control)
	
		clearSelection(edit)
		
	
	proc verScrollLineDown(Edit edit,Event event)=
		lines=len(edit.text)
		client_rect=getClientRect(edit.control)
	
		viewLines=client_rect.h/edit.lineH
	
		if viewLines < lines and edit.firstVisibleRow < lines-viewLines		#!!!!!!!!!!!!
	
			scrollLineDown(edit,client_rect,viewLines-1)#!!!!!!!!!!!!!!!!!!
	
		
			drawTextLine(edit,edit.firstVisibleRow+viewLines-1)#draw last!!!!!!!!
	
			updateVerScroll(edit.firstVisibleRow,viewLines,lines,edit.control)
	
	
	
	proc scrollLineDown(Edit edit, Rect client_rect,int row_count)= #move up
		Rect move_rect
		if row_count >0
	
			move_rect.x=client_rect.x;move_rect.w=client_rect.w
			move_rect.y=client_rect.y+edit.lineH
			move_rect.h=row_count*edit.lineH
			new_y=client_rect.y
			moveRect(edit.hdc,client_rect.x,new_y,move_rect)
	
		edit.firstVisibleRow=edit.firstVisibleRow+1
	
	
	proc verScrollMove(Edit edit,Event event)= 
		Rect move_rect

	
		button_pos=hiWord(event.wParam)

		#---------------------------
		SCROLLINFO si 

		si.cbSize=28
		si.fMask=SIF_RANGE #SIF_POS SIF_PAGE
		
	
		call user32.GetScrollInfo (edit.control.id, SB_VERT, si) 

		scroll_range= si.nMax+1 #nPos, nPage

		#----------------------------
		lines=len(edit.text)
		client_rect=getClientRect(edit.control)
	
		view_lines=client_rect.h/edit.lineH
	
		if button_pos >=0 and button_pos<=scroll_range

			first_visible=button_pos

		
			if first_visible > edit.firstVisibleRow # scroll down
				
				delta=first_visible-edit.firstVisibleRow 
	
				if delta =lines
			new_first=lines-view_lines
	
		edit.firstVisibleRow=new_first#!!!!!!!!!!!!!!!
		edit.cursorRow=new_first+offset
		adjustCursorCol(edit)
	
		drawText(edit,client_rect)#!!!!!!!!!!!!!!!!!!
		clearSelection(edit)
	
		updateVerScroll(edit.firstVisibleRow,view_lines,lines,edit.control)
		drawControl(edit.control) 

	
	
	proc verScrollPageDown(Edit edit)=
	
		lines=len(edit.text)
		client_rect=getClientRect(edit.control)
		view_lines=client_rect.h/edit.lineH
	
		new_first=edit.firstVisibleRow + view_lines-1
		new_last=new_first+view_lines-1
	
		if new_last >=lines
			new_first=lines-view_lines
	
		edit.firstVisibleRow=new_first#!!!!!!!!!!!!!!!
		drawText(edit,client_rect)#!!!!!!!!!!!!!!!!!!
	
		updateVerScroll(edit.firstVisibleRow,view_lines,lines,edit.control)
	
	proc keyPageUp(Edit edit)=
		offset=edit.cursorRow-edit.firstVisibleRow
	
		lines=len(edit.text)
		client_rect=getClientRect(edit.control)
		view_lines=client_rect.h/edit.lineH
	
		new_first=edit.firstVisibleRow - view_lines+1
	
		if new_first <0:new_first=0
	
		edit.firstVisibleRow=new_first#!!!!!!!!!!!!!!!
		edit.cursorRow=new_first+offset
		adjustCursorCol(edit)
		drawText(edit,client_rect)#!!!!!!!!!!!!!!!!!!
	
		clearSelection(edit)
	
		updateVerScroll(edit.firstVisibleRow,view_lines,lines,edit.control)
		drawControl(edit.control) 

	
	proc verScrollPageUp(Edit edit)=
	
		lines=len(edit.text)
		client_rect=getClientRect(edit.control)
		view_lines=client_rect.h/edit.lineH
	
		new_first=edit.firstVisibleRow - view_lines+1
	
		if new_first <0:new_first=0
	
		edit.firstVisibleRow=new_first#!!!!!!!!!!!!!!!
		drawText(edit,client_rect)#!!!!!!!!!!!!!!!!!!
	
		updateVerScroll(edit.firstVisibleRow,view_lines,lines,edit.control)
	
	
	proc changeCursorRow(Edit edit, int incr)=
		edit.cursorRow=edit.cursorRow+incr #!!!!!!!!!!!!!!!!!!!!!!!!!
		Str curLine 
		curLine=edit.text[edit.cursorRow]
		leLine=len(curLine)
		if edit.cursorCol>=leLine
			edit.cursorCol=leLine#-1
	
	
	proc adjustCursorCol(Edit edit)=#**********************************************
		Str curLine 
		curLine=edit.text[edit.cursorRow]
		leLine=len(curLine)
		if edit.cursorCol>=leLine
			edit.cursorCol=leLine#-1
	
	list mouseXYToColLine(Edit edit, int mouseX,int mouseY)=
		ol=[]
	
		Str line;char sign
	
		cliRe=getAbsClientRect(edit.control)
		xt=cliRe.x+edit.leftMargin-edit.viewX 
	
		lineNo=(mouseY-cliRe.y)/edit.lineH 
		dx=mouseX-xt  
	
		line=edit.text[lineNo]
		le=len(line)
		width=0
		for k=0 to le-1
			sign=line[k]
			charW=getCharWidth(edit.hdc,sign)
			width=width+charW 
			if width >= dx
				goto end#=============
		end:#=============
		append(ol,k);append(ol,lineNo) 
		return ol

	#---------------------------------------------------------------------

	proc writeRedo(Edit edit,int opCode,str key)=#****************************************************
		EditOp edit_op; edit_op.opCode=opCode
		edit_op.row=edit.cursorRow;edit_op.col=edit.cursorCol;edit_op.firstVisibleRow=edit.firstVisibleRow
	
		edit_op.letter=key
	
		append(edit.redo,edit_op)
	
	
	proc writeRedo(Edit edit,int opCode)=#****************************************************
		EditOp edit_op; edit_op.opCode=opCode
		edit_op.row=edit.cursorRow;edit_op.col=edit.cursorCol;edit_op.firstVisibleRow=edit.firstVisibleRow
	
		edit_op.selRow=edit.selLastRow; edit_op.selCol=edit.selEndCol
	
		append(edit.redo,edit_op)
	
	proc writeRedoVar(Edit edit,int opCode, str var)=#****************************************************
		EditOp edit_op; edit_op.opCode=opCode
		edit_op.row=edit.cursorRow;edit_op.col=edit.cursorCol;edit_op.firstVisibleRow=edit.firstVisibleRow
	
		edit_op.selRow=edit.selLastRow; edit_op.selCol=edit.selEndCol
	
		edit_op.variable=var
	
		append(edit.redo,edit_op)
	
	
	proc writeRedo(Edit edit,int opCode, list var)=#****************************************************
		EditOp edit_op; edit_op.opCode=opCode
		edit_op.row=edit.cursorRow;edit_op.col=edit.cursorCol;edit_op.firstVisibleRow=edit.firstVisibleRow
	
		edit_op.selRow=edit.selLastRow; edit_op.selCol=edit.selEndCol
	
		edit_op.variable=var
	
		append(edit.redo,edit_op)
	
	
	proc undoLastOP(Edit edit)=
		Str line;text_ala=""; text2=""; new_text="";selection_lines=[]
		edit_op=popEditOp(edit.undo);new_col=0
		if edit_op.opCode
			edit.cursorRow=edit_op.row; edit.cursorCol=edit_op.col;edit.firstVisibleRow=edit_op.firstVisibleRow
	
			if edit_op.opCode=EDIT_OP_INSERT_CHAR 
				
				line=edit.text[edit_op.row]
				text_ala=line.s[edit_op.col]
				delete(line.s,edit_op.col)
	
				writeRedo(edit,edit_op.opCode,text_ala)
	
			elif edit_op.opCode=EDIT_OP_DELETE_CHAR
				delete_char: #----------------------
				line=edit.text[edit_op.row]
				insert(line.s,edit_op.col,edit_op.letter)
	
				writeRedo(edit,edit_op.opCode)
	
			elif edit_op.opCode=EDIT_OP_DELETE_CHAR_1
	
				goto delete_char #----------------------
	
	
			elif edit_op.opCode=EDIT_OP_INSERT_PARAGRAPH
	
				line=edit.text[edit_op.row]; next_row=edit_op.row+1; next=edit.text[next_row]
				line.s=line.s+next.s
				delete(edit.text,next_row)
	
				writeRedo(edit,edit_op.opCode)
	
			elif edit_op.opCode=EDIT_OP_DELETE_PARAGRAPH
				new_row=edit_op.row-1; new_col=edit_op.variable  
	
				line=edit.text[new_row]
	
				text_ala=line.s[0:new_col]
				text2=line.s[new_col:]
				line.s=text_ala
				insert(edit.text,edit_op.row,text2)
	
				writeRedo(edit,edit_op.opCode)
	
			elif edit_op.opCode=EDIT_OP_DELETE_PARAGRAPH_1
	
				new_row=edit_op.row; new_col=edit_op.variable  
	
				line=edit.text[new_row]
	
				text_ala=line.s[0:new_col]
				text2=line.s[new_col:]
				line.s=text2
				insert(edit.text,edit_op.row,text_ala)
	
				writeRedo(edit,edit_op.opCode)
	
			elif edit_op.opCode=EDIT_OP_DELETE_SELECTION
				edit.selLastRow=edit_op.selRow; edit.selEndCol=edit_op.selCol
	
				
				selection_lines=edit_op.variable
				le_selection=len(selection_lines)
		
				if le_selection=1 # one line selection
					text_ala=selection_lines[0]
					line=edit.text[edit_op.row]
					insert(line.s,edit_op.auxCol,text_ala)
	
	
				elif le_selection >1 
					text_ala=selection_lines[0]
	
					line=edit.text[edit_op.auxRow]; new_text=line.s[:edit_op.auxCol];text2=line.s[edit_op.auxCol:]
					line.s=new_text+text_ala
	
					for ind=1 to le_selection-2
						ind_white=ind+edit_op.auxRow 
						new_text=selection_lines[ind]
						insert(edit.text,ind_white,new_text)
					if ind_white
						ind_white=ind_white+1
					else
						ind_white=edit_op.auxRow+1
	
					text_ala=selection_lines[le_selection -1]
					new_text=text_ala+text2
					insert(edit.text,ind_white,new_text)
	
				writeRedo(edit,edit_op.opCode)
	
			elif edit_op.opCode=EDIT_OP_INSERT_TEXT
				line=edit.text[edit_op.row]
				text_ala=line.s[edit_op.col:edit_op.auxCol]
	
				writeRedoVar(edit,edit_op.opCode,text_ala)
	
				delete(line.s,edit_op.col,edit_op.auxCol)
	
	
			elif edit_op.opCode=EDIT_OP_INSERT_LINES
				#first line
				line=edit.text[edit_op.row]
				text_ala=line.s[edit_op.col:]
				
				append(selection_lines,text_ala)
				line.s=line.s[:edit_op.col]
	
				if edit_op.auxRow > edit_op.row+1
					deleted=subButS(edit.text,edit_op.row+1, edit_op.auxRow)
	
					selection_lines=selection_lines+deleted
					
				last_line=edit.text[edit_op.auxRow]
				text_ala=last_line.s[:edit_op.auxCol];append(selection_lines,text_ala)
				text2= last_line.s[edit_op.auxCol:]
	
				for ind= edit_op.auxRow to edit_op.row+1 step -1
					delete(edit.text,ind)
	
				line.s=line.s+text2
	
	
				writeRedo(edit,edit_op.opCode,selection_lines)
	
			draw(edit) #!!!!!!!!!!!!!!!!!!!!
	
	
	
	proc redoLastOP(Edit edit)=
		EditOp edit_op;Str line;text_ala=""; text2=""; new_text="";selection_lines=[];EditOp undo_op
	
		edit_op=popEditOp(edit.redo);new_col=0
	
		if edit_op.opCode
			edit.cursorRow=edit_op.row; edit.cursorCol=edit_op.col;edit.firstVisibleRow=edit_op.firstVisibleRow
	
			if edit_op.opCode=EDIT_OP_INSERT_CHAR 
				key_code=ord(edit_op.letter)
				keyPressed(edit,key_code)
				
	
			elif edit_op.opCode=EDIT_OP_DELETE_CHAR
				keyBackspace(edit)
	
	
			elif edit_op.opCode=EDIT_OP_DELETE_CHAR_1
				keyDelete(edit)
	
			elif edit_op.opCode=EDIT_OP_INSERT_PARAGRAPH
				keyEnter(edit)
	
			elif edit_op.opCode=EDIT_OP_DELETE_PARAGRAPH
	
				keyBackspace(edit)
	
			elif edit_op.opCode=EDIT_OP_DELETE_PARAGRAPH_1
	
				keyDelete(edit)
	
			elif edit_op.opCode=EDIT_OP_DELETE_SELECTION
				edit.selLastRow=edit_op.selRow; edit.selEndCol=edit_op.selCol
	
				delete=1;copy=0;forSelection(edit,delete,copy)
	
	
			elif edit_op.opCode=EDIT_OP_INSERT_TEXT
	
				text_ala=edit_op.variable
				append(selection_lines,text_ala)	
				insertLines(edit,selection_lines)
	
			elif edit_op.opCode=EDIT_OP_INSERT_LINES
	
				selection_lines=edit_op.variable
				insertLines(edit,selection_lines)
	
			#append(edit.undo,undo_op)#!!!!!!!!!!!!!!
	
			draw(edit) #!!!!!!!!!!!!!!!!!!!!
		end:#=========================================

	proc insertLines(Edit edit, list lines)=
		text=""; Str line; before=""; after=""
		le_lines=len(lines)
		if le_lines=1
			text=lines[0]
			line=edit.text[edit.cursorRow]
			insert(line.s,edit.cursorCol,text)
	
			new_col=edit.cursorCol+len(text)
	
			writeUndo(edit,EDIT_OP_INSERT_TEXT,edit.cursorRow,new_col) #!!!!!!!!!!!!!
	
			edit.cursorCol=new_col
	
		elif le_lines>1
			#first line
			line=edit.text[edit.cursorRow]
			before=line.s[:edit.cursorCol]; after=line.s[edit.cursorCol:]
			text=lines[0]
			line.s=before+text #!!!!!!!!!!!!
	
			new_ind=edit.cursorRow+1
			for ind=1 to le_lines-2
				text=lines[ind]
				insert(edit.text,new_ind,text)
				new_ind=new_ind+1
			#last line
			text=lines[le_lines-1] # take last
			new_col=len(text) #!!!!!!!!!!
			text=text+after
			insert(edit.text,new_ind,text)
	
			new_row=edit.cursorRow+le_lines-1
			writeUndo(edit,EDIT_OP_INSERT_LINES,new_row,new_col) #!!!!!!!!!!!!!
	
			edit.cursorRow=new_row
			edit.cursorCol=new_col
	
	
		draw(edit)
	
	proc forSelection(Edit edit, int delete, int copy)= #*******************************
		to_delete=""; Str line; selection_lines=[]; deleted_lines=[];last_str=""
		if edit.selLastRow=edit.cursorRow #one line selection
			line=edit.text[edit.cursorRow]
			if edit.selEndCol > edit.cursorCol
				start_col=edit.cursorCol; end_col=edit.selEndCol
				
			else
	
				start_col=edit.selEndCol; end_col=edit.cursorCol
	
			to_delete=line[start_col:end_col]
			append(selection_lines,to_delete)
	
			if delete
	
				writeUndo(edit,EDIT_OP_DELETE_SELECTION,selection_lines,edit.cursorRow,start_col) #!!!!!!!!!!!!!
	
				delete(line.s,start_col,end_col) #!!!!!!!!!!!!!!!!!!
				edit.cursorCol=start_col #!!!!!!!!!!
			if copy:ok=writeClippboard(selection_lines)  
	
		else # more rows
			#prepare undo 
			if edit.selLastRow > edit.cursorRow
				start_row=edit.cursorRow; start_col=edit.cursorCol
				end_row=edit.selLastRow+1;end_col=edit.selEndCol
			else
				start_row=edit.selLastRow; start_col=edit.selEndCol
				end_row=edit.cursorRow+1; end_col=edit.cursorCol
	
			last_row=end_row-1
			#first selection line
			line=edit.text[start_row]; to_delete=line[start_col:]; append(selection_lines,to_delete)
	
			#whole lines in the middle
			if last_row > start_row+1 # some whole lines
				new_start=start_row+1
				deleted_lines=subButS(edit.text,new_start,last_row)
				selection_lines=selection_lines+deleted_lines
			#last selection line
			last_line=edit.text[last_row]; to_delete=last_line[:end_col]; append(selection_lines,to_delete)
	
			if delete
				writeUndo(edit,EDIT_OP_DELETE_SELECTION,selection_lines,start_row,start_col) #!!!!!!!!!!!!!
		
				#delete 
				line.s=line.s[:start_col]
		
				last_str=last_line.s[end_col:] #!!!!!!!!!!!!
				line.s=line.s+last_str
		
				if last_row > start_row+1 # some whole lines
		
					delete(edit.text,start_row+1,end_row) #!!!!!!!!!
				else #delte last
					delete(edit.text,last_row) #!!!!!!!!!
		
				edit.cursorRow=start_row #!!!!!!!!!!!!!
				edit.cursorCol=start_col #!!!!!!!!!!
	
			if copy:ok=writeClippboard(selection_lines) 
		if delete
			edit.selLastRow=-1;edit.selEndCol=-1 #!!!!!!!!!!1
			draw(edit) #!!!!!!!!!!!!!!!!
	
	#-------------------------------------------------------------------

	proc mouseLBD(Edit edit, Event event)=# ***************************************************


		mouse_x=loWord(event.lParam)
		mouse_y=hiWord(event.lParam)

		
	
		Str line;char letter; old=-1
	
		cliRe=getClientRect(edit.control)
	
		lineNo=(mouse_y-cliRe.y)/edit.lineH  +edit.firstVisibleRow  
		if lineNo >=0
	
			le_text=len(edit.text)
			if lineNo >=le_text:lineNo=le_text-1 #!!!!!!!!!!!!!!
		
			xt=cliRe.x+edit.leftMargin-edit.viewX 
			if mouse_x> xt
			
				line=edit.text[lineNo]
				le=len(line)
	
				for k=0 to le-1
					letter=line[k]
		
					if toInt(letter)=9 #tab code
						if edit.tabLength>0
							xt=tabPosition(edit,xt)
	
					else
						charW=getCharWidth(edit.hdc,letter)  
						xt=xt+charW 
					if xt >= mouse_x
						goto end#=============
			end:#=============
			clearSelection(edit) #!!!!!!!!!!!!!!!!!
			if lineNo != edit.cursorRow
				
				old=edit.cursorRow
				edit.cursorRow=lineNo #!!!!!!!!!!!!!
	
			edit.cursorCol=k #!!!!!!!!!!!!!!!
			edit.mouseLBD=1 #!!!!!!!!!!!!!!!
	
			if old >=0 :drawTextLine(edit,old)
			drawTextLine(edit,edit.cursorRow)

			drawControl(edit.control)

	
	proc mouseLBU(Edit edit, Event event)=#******************************************************
	
		edit.mouseLBD=0 #!!!!!!!!!!!!!!!!!
	
	proc mouseMove(Edit edit,Event event)= 

	
		mouse_x=loWord(event.lParam)
		mouse_y=hiWord(event.lParam)
	
		Str line;char letter; old=-1
	
		if edit.mouseLBD
			cliRe=getClientRect(edit.control)
		
			lineNo=(mouse_y-cliRe.y)/edit.lineH +edit.firstVisibleRow 
	
			text_len=len(edit.text)
	
			if lineNo >=0 and lineNo < text_len
	
				xt=cliRe.x+edit.leftMargin-edit.viewX 
				if mouse_x> xt
		
					line=edit.text[lineNo]
					le=len(line)
	
					for k=0 to le-1
						letter=line[k] 
			
						if toInt(letter)=9 #tab code
							if edit.tabLength>0
								xt=tabPosition(edit,xt)
		
						else
							charW=getCharWidth(edit.hdc,letter) 
							xt=xt+charW 
						if xt >= mouse_x
							goto end#=============
	
				end:#=============
				edit.selLastRow=lineNo
				edit.selEndCol=k
		
				if lineNo = edit.cursorRow 
					if k != edit.cursorCol
						drawTextLine(edit,lineNo) #draw with selection
				elif lineNo > edit.cursorRow
					for ind= edit.cursorRow to lineNo
						drawTextLine(edit,ind)
	
				else
					for ind= lineNo to edit.cursorRow
						drawTextLine(edit,ind)


	#----------------------------------------------------------------

	proc horScroll(Edit edit, Event event)=

	
		code=loWord(event.wParam)

		#---------------------------
		SCROLLINFO si 

		si.cbSize=28
		si.fMask=SIF_RANGE #SIF_POS SIF_PAGE
		
	
		call user32.GetScrollInfo (edit.control.id, SB_HORZ, si) 

		scroll_range= si.nMax+1 #nPos, nPage

		
		if code=H_SCROLL_RIGHT: horScrollRight(edit, scroll_range)
		elif code=H_SCROLL_LEFT: horScrollLeft(edit, scroll_range)



		elif code=H_SCROLL_MOVE: horScrollMove(edit, scroll_range,event)


	proc horScrollRight(Edit edit, int scroll_range)=#****************************************************
	
		null=0
		disX=edit.tabLength
		horScrollProc(edit,disX,null,scroll_range)
	
	proc horScrollLeft(Edit edit, int scroll_range)=
	
		null=0
		disX=0-edit.tabLength 
		horScrollProc(edit,disX,null,scroll_range)
	
	proc horScrollMove(Edit edit, int scroll_range, Event event)=
		null=0
		button_pos=hiWord(event.wParam)

	
		horScrollProc(edit,null,button_pos,scroll_range)
	
	

	proc horScrollProc(Edit edit,int dX, int buttonPos,int scrollRange)= 
		#if dX >0 to the right

		rect=getClientRect(edit.control) 
		viewX=edit.viewX
	
		if edit.horScrollRange >0
			if edit.horScrollRange > rect.w
		
				if dX  #left or right button
					viewX1=viewX+dX
					if viewX1<0: viewX1=0
					elif viewX1 > edit.horScrollRange-rect.w
	
						edit.horScrollRange=viewX1+rect.w #!!!!!!!!!!!
					
					if viewX1 != viewX
						scroll_et1: #-------------------------------------------------
				
						updateHorScroll(viewX1, rect.w, edit.horScrollRange,edit.control)
						
						edit.viewX=viewX1 #!!!!!!!!!!!!!!!!!!
						drawText(edit,rect) #!!!!!!!!!!!!!! 
				else  #move on
					viewX1=(edit.horScrollRange-rect.w)*buttonPos/scrollRange #!!!!!!!!!!!!!!!!!
					if viewX1 != viewX
						
						goto scroll_et1 #-------------------------------------------------

	#Fifo and EditOp +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	
	proc append(Fifo fifo, EditOp x)=
		FifoElement element;FifoElement first;FifoElement beforeLast;FifoElement last
		element.value=x
	
		if fifo.first=0 
			fifo.last=element
			fifo.first=element
	
			fifo.len=1
	
		else
			first=fifo.first
	
			element.next=first
			first.prev=element
	
			fifo.first=element
	
			fifo.len=fifo.len+1
	
			if fifo.maxLen
				if fifo.len>fifo.maxLen
					last=fifo.last
					beforeLast=last.prev
					beforeLast.next=0
					fifo.last=beforeLast
					fifo.len=fifo.len-1
	
	EditOp popEditOp(Fifo fifo)=
		EditOp res;FifoElement element
		if fifo.first !=0
			element=fifo.first
			fifo.first=element.next
			res=element.value
			fifo.len=fifo.len-1
		return res
	
	
	#Fifo and EditOp end ====================================================================

	# to implement ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	int writeClippboard(list selection_lines)=
		res=1; return res

	#===============================================================================================================================


#main ++++++++++++++++++++++++++++++++++++++++++++++++++++++++

initGui() #!!!!!!!!!!!!!!!!!!!!


screen=getScreen() 

style=0;mode=0;parentId=0
main_x=screen.w/4; main_y=screen.h/8+40
main_w=screen.w-main_x-40; main_h=screen.h-main_y-40 

mainWnd= Window(main_x,main_y,main_w,main_h,style,mode,parentId,"document 1.txt")  

if mainWnd.id=0 :printLastError(); goto end #========================

global guiFont; int guiFont

margin=20
edit_w=main_w-main_w/8-margin
edit_h=main_h-main_h/8-margin
edit=Edit(margin,margin,edit_w,edit_h,guiFont,mainWnd) 


tab=chr(9)
for k=1 to 120
	s=toStr(k)
	text=tab+s+" Alice has a cat 1234abcdefghijklmnopqxyz "+s
	ns=append(edit.text,text)

last=edit.text[edit.cursorRow]
edit.cursorCol=len(last)





setVerScrollRange(edit)  #!!!!!!!!!!!!!!!


show(mainWnd)

setFocus(edit.control)
eventLoop()
end: #========================