View difference between Paste ID: qWYdsRXL and aKyMYgbF
SHOW: | | - or go back to the newest paste.
1
-- usage:
2
--	taco
3
--	taco filename
4
5
local tArgs = {...}
6
local betaKey = ""
7
local currentFile = ""
8
local isSaved = true
9
local isChanged = false
10
local fileLinesArr = {""}
11
local curLine,curCol,lastCol=1,0,0
12
local menus = {}
13
local inMenu=false
14
local selectedMenu = 1
15
local selectedSubMenu = 1
16
local running = true
17
local config = {isFullScreen = false, clipboard=""}
18
local showFirstTimeMessage = false
19
local showAboutBox=false
20
local collectedInputs = {file="My Input Data"}
21
local collectedInputsCursor = {file=1}
22
local collectedInputsOffsets = {file=0}
23
local collectedInputsSize = {file=0}
24
local w,h = term.getSize()
25
local scrollOffsetX,scrollOffsetY = 0,0
26
local isBlinking = false
27
local state = "edit"
28
local message = {}
29
local showingMessage=false
30
local showingFileDialog = false
31
local selectedMessageOption=1
32
local lastBlinkTime = 0
33
sleep(0.1)
34
local timer = os.startTimer(0)
35
36
local function setColors(monitor, bg, fg, bg2, fg2)
37
	 if monitor then
38
		if monitor.isColor() then
39
			monitor.setBackgroundColor(bg)
40
			monitor.setTextColor(fg)
41
		else
42
			monitor.setBackgroundColor(bg2)
43
			monitor.setTextColor(fg2)
44
		end
45
	end
46
end
47
48
local function checkLinePosition()
49
		local maxLines = #fileLinesArr
50
		if curLine < 1 then
51
				curLine = 1
52
		elseif curLine > #fileLinesArr then
53
				curLine = maxLines
54
		end
55
		local yOffset = 2
56
		if config.isFullScreen then
57
			yOffset = 0
58
		end
59
		if scrollOffsetY > h-yOffset-curLine then
60
				scrollOffsetY=h-yOffset-curLine
61
		elseif scrollOffsetY < 1-curLine then
62
				scrollOffsetY=1-curLine
63
		end
64
end
65
local function checkColPosition()
66
		if curCol < 0 then
67
			curCol = 0
68
		elseif curCol > string.len(fileLinesArr[curLine]) then
69
			curCol = string.len(fileLinesArr[curLine])
70
		end
71
		local total = h-3 --todo: possible bug
72
		if #fileLinesArr < total then
73
				total = #fileLinesArr
74
		end
75
		local padWidth = string.len(tostring(total))
76
		local workingWidth = w - padWidth - 1
77
		
78
		if scrollOffsetX >= workingWidth - curCol-1 then
79
				scrollOffsetX=workingWidth-curCol-1
80
		elseif scrollOffsetX < 0-curCol then
81
				scrollOffsetX=0-curCol
82
		end
83
end
84
local function checkMenuPositions()
85
	if selectedMenu < 1 then
86
		selectedMenu = #menus
87
		elseif selectedMenu > #menus then
88
			selectedMenu = 1
89
	end
90
	if selectedSubMenu < 1 then
91
		selectedSubMenu = #menus[selectedMenu].items
92
	elseif selectedSubMenu > #menus[selectedMenu].items then
93
		selectedSubMenu = 1
94
	end
95
end
96
local function checkMessageOptionPositions()
97
	if selectedMessageOption < 1 then
98
		selectedMessageOption = #message.footer
99
	elseif selectedMessageOption > #message.footer then
100
		selectedMessageOption = 1
101
	end
102
end
103
local function loadFile(file)
104
		if fs.exists(file) and not fs.isDir(file) then
105
				local tmpArr = {}
106
				local h = fs.open(file, "r")
107
				while true do
108
						local data = h.readLine()
109
						if data == nil then break end
110
						table.insert(tmpArr, data)
111
				end
112
				h.close()
113
				return tmpArr
114
		end
115
		return null
116
end
117
local function openFile(file)
118
	local data = loadFile(file)
119
	if data then
120
		fileLinesArr = {""}
121
		currentFile = file
122
		isSaved = false
123
		isChanged = false
124
		scrollOffsetX,scrollOffsetY=0,0
125
		if data then
126
			fileLinesArr = data
127
			isSaved = true
128
		end
129
		curLine,curCol,lastCol=1,0,0
130
		checkLinePosition()
131
		checkColPosition()
132
		return true
133
	end
134
	return false
135
end
136
local function saveFile(file, dataArr)
137
		local tmpArr = {}
138
		local h = fs.open(file, "w")
139
		if h then
140
			for i=1, #dataArr do
141
					h.writeLine(dataArr[i])
142
			end
143
			h.close()
144
			isSaved = true
145
			isChanged = false
146
			return true
147
		end
148
		return false
149
end
150
local function loadSettings()
151
		if fs.exists("taco.db") then
152
				local cfg
153
				local h = fs.open("taco.db", "r")
154
				while true do
155
						data = h.readLine()
156
						if data == nil then break end
157
						if data == "--[[CONFIG:" then
158
								local tmpCfg = h.readAll()
159
								cfg=textutils.unserialize(string.sub(tmpCfg,1,string.len(tmpCfg)-2))
160
						end
161
				end
162
				h.close()
163
				if cfg then
164
						if cfg.isFullScreen then
165
								config.isFullScreen = cfg.isFullScreen
166
						end
167
						if cfg.clipboard then
168
								config.clipboard = cfg.clipboard
169
						end
170
				end
171
		else
172
				showFirstTimeMessage = true
173
		end
174
end
175
local function saveSettings()
176
		settingsStr=textutils.serialize(config)
177
		local h = fs.open("taco.db", "w")
178
		h.writeLine('print("This is a settings file for TACO :)")')
179
		h.writeLine('--[[CONFIG:')
180
		h.writeLine(settingsStr)
181
		h.writeLine(']]')
182
		h.close()
183
end
184
local function newFile()
185
		currentFile = ""
186
		fileLinesArr={""}
187
		curLine,curCol,lastCol=1,0,0
188
		checkLinePosition()
189
		checkColPosition()
190
		isSaved = true
191
		isChanged = false
192
end
193
		
194
table.insert(menus, {
195
												name="File",
196
												hotkey=keys.f,
197
												items={
198
																{"New", "N", "new_file", true},
199
																{"Open..", "O", "open_file", true},
200
																{"Save", "S", "save_file", false},
201
																{"Save As..", "A", "saveas_file", false},
202
																{"--"},
203
																{"Revert", "R", "revert_file", false},
204
																--{"Print..", "P", "print_file", false},
205
																--{"Run Script", "E", "run_file", false},
206
																{"--"},
207
																{"Exit", "X", "exit_app", true}
208
														}
209
										})
210
table.insert(menus, {
211
												name="Edit",
212
												hotkey=keys.e,
213
												items={
214
																--{"Cut", "X", "cut_selection", false},
215
																--{"Copy", "C", "copy_selection", false},
216
																--{"Paste", "V", "paste_selection", false},
217
																--{"--"},
218
																--{"Delete", "D", "clear_selection", false},
219
																--{"--"},
220
																{"Cut Line", "K", "cut_line", false},
221
																{"Copy Line", "J", "copy_line", false},
222
																{"Paste Line", "U", "paste_line", false},
223
																{"--"},
224
																{"Delete Line", "R", "delete_line", false},
225
																{"--"},
226
																{"Clone Line", "R", "clone_line", false},
227
														}
228
										})
229
										--[[
230
table.insert(menus, {
231
												name="Search",
232
												hotkey=keys.s,
233
												items={
234
																{"Find..", "F", "find_text", false},
235
																{"Replace..", "R", "replace_text", false}
236
														}
237
										})]]
238
table.insert(menus, {
239
												name="Options",
240
												hotkey=keys.o,
241
												items={
242
																{"Full Screen Mode", "F", "fullscreen_toggle", false},
243
																--{"Settings..", "S", "show_settings", false}
244
														}
245
										})
246
table.insert(menus, {
247
												name="Help",
248
												hotkey=keys.h,
249
												items={
250
																--{"Help", "H", "show_help", true},
251
																{"Grab Updates", "U", "perform_update", true},
252
																{"--"},
253
																{"About TACO", "A", "show_about", true},
254
														}
255
										})
256
local function lpad(str, len, char)
257
		if char == nil then char = ' ' end
258
		local i = len - #str
259
		if i >= 0 then
260
			return string.rep(char, i) .. str
261
		else
262
			return str
263
		end
264
end
265
local function rpad(str, len, char)
266
		if char == nil then char = ' ' end
267
		local i = len - #str
268
		if i >= 0 then
269
			return str .. string.rep(char, i)
270
		else
271
			return str
272
		end
273
end
274
local function getMenuOffset(menu)
275
	local menuOffset = 3
276
277
	for i = 1, selectedMenu - 1 do
278
		menuOffset = menuOffset + string.len(menus[i].name) + 2
279
	end
280
281
	return menuOffset
282
end
283
local function getMenuWidth(menu)
284
	menuWidth = 1
285
286
	for i = 1, #menus[selectedMenu].items do
287
		local len = string.len(menus[selectedMenu].items[i][1]) + 2
288
289
		if len > menuWidth then
290
			menuWidth = len
291
		end
292
	end
293
294
	return menuWidth
295
end
296
local function getMenuHeight(menu)
297
	return #menus[selectedMenu].items
298
end
299
local function drawScreen(monitor)
300
		w,h = monitor.getSize()
301
		monitor.setBackgroundColor(colors.black)
302
		monitor.clear()
303
		--header bar
304
		local guiOffset = 1
305
		local lineTotalOffset = 2
306
		if config.isFullScreen then
307
				guiOffset = 0
308
				lineTotalOffset = 0
309
		end
310
		--editor area
311
		local ii=1
312
		local total = h-lineTotalOffset-scrollOffsetY+curLine
313
		if #fileLinesArr < total then
314
				total = #fileLinesArr
315
		end
316
		local padWidth = string.len(tostring(total))
317
		for i=1+guiOffset, h-(guiOffset/2) do
318
				local currentLineIndex = ii-scrollOffsetY
319
				local workingWidth = w - padWidth - 1
320
				if 1==2 then
321
					workingWidth=workingWidth-1 --scrollbar
322
				end
323
				monitor.setCursorPos(1,i)
324
				setColors(monitor, colors.blue, colors.lightGray, colors.black, colors.white)
325
				monitor.write(string.rep(" ", w)) --subtract the two "+"'s
326
				if currentLineIndex <= #fileLinesArr then
327
						local currentLine = fileLinesArr[currentLineIndex]
328
						setColors(monitor, colors.white, colors.red, colors.white, colors.black)
329
						monitor.setCursorPos(1,i)
330
						monitor.write(lpad(tostring(currentLineIndex), padWidth, " "))
331
						if curLine == currentLineIndex then
332
								setColors(monitor, colors.lightBlue, colors.white, colors.black, colors.white)
333
						else
334
								setColors(monitor, colors.blue, colors.lightGray, colors.black, colors.white)
335
						end
336
						monitor.setCursorPos(padWidth+1,ii+guiOffset)
337
						currentLineFit = currentLine
338
						if currentLineFit then
339
								currentLineFit = string.sub(currentLineFit, -scrollOffsetX+1, string.len(currentLineFit))
340
								if string.len(currentLineFit) > workingWidth then
341
										currentLineFit = string.sub(currentLineFit, 1, workingWidth)
342
								end
343
								monitor.write(" "..rpad(currentLineFit, workingWidth, " ").." ")
344
						end
345
						if curLine == currentLineIndex and (isBlinking or inMenu) then
346
								monitor.setCursorPos(padWidth+2+curCol+scrollOffsetX,i)
347
								setColors(monitor, colors.white, colors.lightBlue, colors.white, colors.black)
348
								local msg = string.sub(currentLineFit,curCol+scrollOffsetX+1,curCol+scrollOffsetX+1)
349
								if msg == "" then msg = " " end
350
								monitor.write(msg)
351
						end
352
				end
353
				ii=ii+1
354
		end
355
		
356
		if not config.isFullScreen or inMenu then
357
				--footer bar
358
				setColors(monitor, colors.lightGray, colors.black, colors.white, colors.black)
359
				monitor.setCursorPos(1,h)
360
				monitor.write(string.rep(" ", w))
361
				
362
				monitor.setCursorPos(1,h)
363
				if not isSaved or isChanged then
364
					setColors(monitor, colors.lightGray, colors.red, colors.white, colors.black)
365
					monitor.write("*")
366
				end
367
				if currentFile == "" then
368
					setColors(monitor, colors.lightGray, colors.green, colors.white, colors.black)
369
					monitor.write("new_file")
370
				else
371
					monitor.write(currentFile)
372
				end
373
				
374
				setColors(monitor, colors.lightGray, colors.black, colors.white, colors.black)
375
				local footerMsg = "Ln "..curLine..":"..#fileLinesArr.."	Col "..(curCol+1) --.." XOff="..scrollOffsetX
376
				monitor.setCursorPos(w-string.len(footerMsg)+1,h)
377
				monitor.write(footerMsg)
378
		
379
				--header bar
380
				monitor.setCursorPos(1,1)
381
				setColors(monitor, colors.lightGray, colors.black, colors.white, colors.black)
382
				monitor.write(string.rep(" ", w))
383
				monitor.setCursorPos(2,1)
384
				for i=1, #menus do
385
						if inMenu and i == selectedMenu then
386
								setColors(monitor, colors.black, colors.white, colors.black, colors.white)
387
						else
388
								setColors(monitor, colors.lightGray, colors.black, colors.white, colors.black)
389
						end
390
						monitor.write(" "..menus[i].name.." ")
391
				end
392
				
393
				-- Time
394
				local time = os.time()
395
				local timeFmt = textutils.formatTime(time, false)
396
				local timeLen = string.len(timeFmt)
397
				monitor.setCursorPos(w-timeLen,1)
398
				setColors(monitor, colors.lightGray, colors.black, colors.white, colors.black)
399
				monitor.write(timeFmt)
400
		end
401
402
		if inMenu then
403
				monitor.setCursorPos(1,1)
404
				setColors(monitor, colors.lightGray, colors.black, colors.white, colors.black)
405
				local menuWidth = getMenuWidth(selectedMenu)
406
				local menuOffset = getMenuOffset(selectedMenu)
407
				for i=1, #menus[selectedMenu].items do
408
						if i == selectedSubMenu then
409
								setColors(monitor, colors.black, colors.white, colors.black, colors.white)
410
						else
411
								setColors(monitor, colors.lightGray, colors.black, colors.white, colors.black)
412
						end
413
						posX = menuOffset
414
						posY = i + 1
415
						monitor.setCursorPos(posX,posY)
416
						monitor.write(string.rep(" ", menuWidth))
417
						monitor.setCursorPos(posX,posY)
418
						local str = menus[selectedMenu].items[i][1]
419
						if str == "--" then
420
								if monitor.isColor() then
421
									monitor.setTextColor(colors.gray)
422
								else
423
									monitor.setTextColor(colors.black)
424
								end
425
								monitor.write(string.rep("-", menuWidth))
426
						else
427
								monitor.write(" "..str.." ")
428
						end
429
				end
430
		end
431
		
432
end
433
434
function updateAllTheThings()
435
		shell.run("market get gjdh1m taco "..betaKey.." y")
436
end
437
local function resetBlink()
438
		lastBlinkTime = os.clock()+.5
439
		isBlinking = true
440
end
441
local function centerText(monitor, tY, tText)
442
		local offX = (w+1)/2 - (string.len(tText)-1)/2
443
		monitor.setCursorPos(offX, tY)
444
		monitor.write(tText)
445
end
446
local function centerTextWidth(monitor, tX, tY, width, tText)
447
		local offX = (width+1)/2 - (string.len(tText)-1)/2
448
		monitor.setCursorPos(offX+tX, tY)
449
		monitor.write(tText)
450
end
451
local logo = {
452
"		 1111111111	";
453
"	11115e454e5e11 ";
454
" 11545e5111111111";
455
"1154e411111111111";
456
"1e455111111111111";
457
"15ec5111111111111";
458
"1cccc1111111111	";
459
"1cccc111111			";
460
" 111111					";
461
}
462
--[[Stolen Shamelessly from nPaintPro - http://pastebin.com/4QmTuJGU]]
463
local function getColourOf(hex)
464
	local value = tonumber(hex, 16)
465
	if not value then return nil end
466
	value = math.pow(2,value)
467
	return value
468
end
469
local function drawPictureTable(mon, image, xinit, yinit, alpha)
470
	if not alpha then alpha = 1 end
471
	for y=1,#image do
472
		for x=1,#image[y] do
473
			mon.setCursorPos(xinit + x-1, yinit + y-1)
474
			local col = getColourOf(string.sub(image[y], x, x))
475
			if not col then col = alpha end
476
			if term.isColor() then
477
				mon.setBackgroundColour(col)
478
			else
479
				local pixel = string.sub(image[y], x, x)
480
				if pixel == "c" or pixel == "5" or pixel == " " then
481
					mon.setBackgroundColour(colors.white)
482
				else
483
					mon.setBackgroundColour(colors.black)
484
				end
485
			end
486
			mon.write(" ")
487
		end
488
	end
489
end
490
--[[End Theft]]
491
local function trySaveFileFromDialog()
492
	currentFile = collectedInputs.file
493
	if saveFile(currentFile, fileLinesArr) then
494
		showingFileDialog=false
495
	else
496
		messageBox("Error!", {"Couldn't save file!", "Try another name.."}, {{"OK",null}})
497
	end
498
end
499
local function tryOpenFileFromDialog()
500
	if openFile(collectedInputs.file) then
501
		showingFileDialog=false
502
	else
503
		messageBox("Error!", {"Couldn't open file!"}, {{"OK",null}})
504
	end
505
end
506
local function hideFileDialog()
507
	showingFileDialog=false
508
end
509
local fileDialog={}
510
fileDialog.title="Open File"
511
fileDialog.basePath="/"
512
fileDialog.currentTab=1
513
fileDialog.currentTabMax=4
514
fileDialog.dirScrollOffset=0
515
fileDialog.fileScrollOffset=0
516
fileDialog.dirSelected=1
517
fileDialog.fileSelected=1
518
fileDialog.currentPathFiles={}
519
fileDialog.currentPathFolders={}
520
fileDialog.selectedFooterOption=1
521
fileDialog.footer={}
522
local function addSlashIfNeeded(path)
523
	local len = string.len(path)
524
	if string.sub(path, len, len) ~= "/" then
525
		return path.."/"
526
	else
527
		return path
528
	end
529
end
530
local function addSlashIfNeededLeft(path)
531
	if string.sub(path, 1,1) ~= "/" then
532
		return "/"..path
533
	else
534
		return path
535
	end
536
end
537
local function getFilePath(file)
538
		local fName = fs.getName(file)
539
		local lenBpath = string.len(file)
540
		local lenFname = string.len(fName)
541
		return string.sub(file, 1, lenBpath - lenFname-1)
542
end
543
local function prepareDialog()
544
	local tmpList = fs.list(fileDialog.basePath)
545
	local tmpFileArr,tmpFolderArr={},{}
546
	fileDialog.basePath = addSlashIfNeeded(fileDialog.basePath)
547
	if fileDialog.basePath ~= "/" then
548
			table.insert(tmpFolderArr, {"..", getFilePath(fileDialog.basePath)})
549
	end
550
	for key, file in ipairs(tmpList) do
551
		local len = string.len(fileDialog.basePath)
552
		file = addSlashIfNeeded(fileDialog.basePath)..file
553
		if fs.isDir(file) then
554
			table.insert(tmpFolderArr, {fs.getName(file), file.."/"})
555
		else
556
			table.insert(tmpFileArr, {fs.getName(file), file})
557
		end
558
	end
559
	fileDialog.currentPathFiles = tmpFileArr
560
	fileDialog.currentPathFolders = tmpFolderArr
561
	fileDialog.dirScrollOffset=0
562
	fileDialog.fileScrollOffset=0
563
	checkDialogLimits()
564
end
565
function dialogReset()
566
	fileDialog.currentTab=1
567
	fileDialog.dirScrollOffset=0
568
	fileDialog.fileScrollOffset=0
569
	fileDialog.dirSelected=1
570
	fileDialog.fileSelected=1
571
end
572
local dirFileListHeight = 1
573
function checkDialogLimits()
574
	if fileDialog.selectedFooterOption < 1 then
575
		fileDialog.selectedFooterOption = #fileDialog.footer
576
	end
577
	if fileDialog.selectedFooterOption > #fileDialog.footer then
578
		fileDialog.selectedFooterOption = 1
579
	end
580
581
	if fileDialog.dirSelected < 1 then
582
		fileDialog.dirSelected = 1
583
	end
584
	if fileDialog.fileSelected < 1 then
585
		fileDialog.fileSelected = 1
586
	end
587
	if fileDialog.fileSelected > #fileDialog.currentPathFiles then
588
		fileDialog.fileSelected = #fileDialog.currentPathFiles
589
	end
590
	if fileDialog.dirSelected > #fileDialog.currentPathFolders then
591
		fileDialog.dirSelected = #fileDialog.currentPathFolders
592
	end
593
	
594
	if fileDialog.dirScrollOffset > dirFileListHeight-fileDialog.dirSelected+1 then
595
			fileDialog.dirScrollOffset=dirFileListHeight-fileDialog.dirSelected+1
596
	elseif fileDialog.dirScrollOffset < 1-fileDialog.dirSelected then
597
			fileDialog.dirScrollOffset=1-fileDialog.dirSelected
598
	end
599
	
600
	if fileDialog.fileScrollOffset > dirFileListHeight-fileDialog.fileSelected+1 then
601
			fileDialog.fileScrollOffset=dirFileListHeight-fileDialog.fileSelected+1
602
	elseif fileDialog.fileScrollOffset < 1-fileDialog.fileSelected then
603
			fileDialog.fileScrollOffset=1-fileDialog.fileSelected
604
	end
605
	
606
	
607
	
608
	if collectedInputsCursor.file < 0 then
609
			collectedInputsCursor.file = 0
610
	elseif collectedInputsCursor.file > string.len(collectedInputs.file) then
611
			collectedInputsCursor.file = string.len(collectedInputs.file)
612
	end
613
	if collectedInputsOffsets.file >= collectedInputsSize.file - collectedInputsCursor.file-1 then
614
			collectedInputsOffsets.file=collectedInputsSize.file-collectedInputsCursor.file-1
615
	elseif collectedInputsOffsets.file < 0-collectedInputsCursor.file then
616
			collectedInputsOffsets.file=0-collectedInputsCursor.file
617
	end
618
end
619
function showFileSaveAsDialog()
620
	if fs.exists(currentFile) and not fs.isDir(currentFile) then
621
		fileDialog.basePath=addSlashIfNeededLeft(shell.resolve(getFilePath(currentFile)))
622
	else
623
		--fileDialog.basePath=addSlashIfNeededLeft(shell.resolve(""))
624
	end
625
	prepareDialog()
626
	dialogReset()
627
	fileDialog.title="Save File As.."
628
	collectedInputs.file = addSlashIfNeededLeft(shell.resolve(currentFile))
629
	collectedInputsCursor.file = string.len(collectedInputs.file)
630
	collectedInputsOffsets.file = 0
631
	collectedInputsSize.file = 0
632
	fileDialog.footer={{"Save",trySaveFileFromDialog},{"Cancel",hideFileDialog}}
633
	showingFileDialog = true
634
end
635
function showFileOpenDialog()
636
	if fs.exists(currentFile) and not fs.isDir(currentFile) then
637
		fileDialog.basePath=addSlashIfNeededLeft(shell.resolve(getFilePath(currentFile)))
638
	else
639
		--fileDialog.basePath=addSlashIfNeededLeft(shell.resolve(""))
640
	end
641
	prepareDialog()
642
	dialogReset()
643
	fileDialog.title="Open File"
644
	collectedInputs.file = addSlashIfNeededLeft(shell.resolve(currentFile))
645
	collectedInputsCursor.file = string.len(collectedInputs.file)
646
	collectedInputsOffsets.file = 0
647
	collectedInputsSize.file = 0
648
	fileDialog.footer={{"Open",tryOpenFileFromDialog},{"Cancel",hideFileDialog}}
649
	showingFileDialog = true
650
end
651
function drawFileDialog(monitor)
652
		w,h = monitor.getSize()
653
		local height = h-2
654
		local width = w-4
655
		local offX = (w+1)/2 - (width-1)/2
656
		local offY = (h+1)/2 - (height-1)/2
657
		local footerMsg = ""
658
		for o=1, #fileDialog.footer do
659
			local item = fileDialog.footer[o][1]
660
			if fileDialog.selectedFooterOption == o then
661
				item = "["..item.."]"
662
			else
663
				item = " "..item.." "
664
			end
665
			if o > 1 then
666
				item = " "..item
667
			end
668
			footerMsg=footerMsg..item
669
		end
670
		if monitor.isColor() then
671
			monitor.setBackgroundColor(colors.cyan)
672
		else
673
			monitor.setBackgroundColor(colors.black)
674
		end
675
		monitor.clear()
676
		for i=1, height do
677
				setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
678
				monitor.setCursorPos(offX, offY+i-1)
679
				if i == 1 or i == height then
680
						monitor.write("+")
681
						monitor.write(string.rep("-", width-2))
682
						monitor.write("+")
683
						if i == 1 then
684
								setColors(monitor, colors.black, colors.yellow, colors.white, colors.black)
685
								centerText(monitor, offY+i-1, " "..fileDialog.title.." ")
686
								setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
687
						elseif i == height then
688
								if fileDialog.currentTab == 4 then
689
									setColors(monitor, colors.black, colors.white, colors.black, colors.white)
690
								else
691
									setColors(monitor, colors.lightGray, colors.white, colors.white, colors.black)
692
								end
693
								centerText(monitor, offY+i-1, " "..footerMsg.." ")
694
								setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
695
						end
696
				else
697
						setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
698
						monitor.write("|")
699
						setColors(monitor, colors.white, colors.black, colors.white, colors.black)
700
						monitor.write(string.rep(" ", width-2))
701
						setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
702
						monitor.write("|")
703
				end
704
		end
705
		setColors(monitor, colors.white, colors.gray, colors.white, colors.black)
706
		monitor.setCursorPos(offX + 2, offY + 2)
707
		monitor.write("File: ")
708
		if fileDialog.currentTab == 1 then
709
			setColors(monitor, colors.black, colors.white, colors.black, colors.white)
710
		else
711
			setColors(monitor, colors.lightGray, colors.white, colors.black, colors.white)
712
		end
713
		local workingWidth = width - 10
714
		local textWidth = workingWidth
715
		collectedInputsSize.file = textWidth
716
		monitor.write(string.rep(" ", workingWidth))
717
		monitor.setCursorPos(offX + 8, offY + 2)		
718
719
		currentLineFit = collectedInputs.file
720
		inputCursor = collectedInputsCursor.file
721
		inputOffsetX = collectedInputsOffsets.file
722
		if currentLineFit then
723
				currentLineFit = string.sub(currentLineFit, -inputOffsetX+1, string.len(currentLineFit))
724
				if string.len(currentLineFit) > textWidth then
725
						currentLineFit = string.sub(currentLineFit, 1, textWidth)
726
				end
727
				monitor.write(rpad(currentLineFit, textWidth, " "))
728
		end
729
		if fileDialog.currentTab == 1 and isBlinking then
730
				monitor.setCursorPos(offX+8+inputCursor+inputOffsetX,offY + 2) 
731
				setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
732
				local msg = string.sub(currentLineFit,inputCursor+inputOffsetX+1,inputCursor+inputOffsetX+1)
733
				if msg == "" then msg = " " end
734
				monitor.write(msg)
735
		end
736
						
737
		
738
		local fileStart = 15
739
		setColors(monitor, colors.white, colors.gray, colors.white, colors.black)
740
		monitor.setCursorPos(offX + 2, offY + 4)
741
		monitor.write("Dir: ")
742
		monitor.setCursorPos(offX + fileStart, offY + 4)
743
		monitor.write("Files: "..fileDialog.basePath)
744
		
745
		dirFileListHeight = height - offY - 6
746
		for i=0, dirFileListHeight do
747
			local dirIndex = i+1-fileDialog.dirScrollOffset
748
			local fileIndex = i+1-fileDialog.fileScrollOffset
749
				
750
			if fileDialog.currentTab == 2 then
751
				setColors(monitor, colors.black, colors.white, colors.black, colors.white)
752
			else
753
				setColors(monitor, colors.lightGray, colors.white, colors.black, colors.white)
754
			end
755
			monitor.setCursorPos(offX + 2, offY + 5+i)
756
			monitor.write(string.rep(" ", fileStart - offX))
757
			if fileDialog.currentPathFolders[dirIndex] then
758
				if fileDialog.currentTab == 2 and dirIndex == fileDialog.dirSelected then
759
					setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
760
				end
761
				monitor.setCursorPos(offX + 2, offY + 5+i)
762
				monitor.write(fileDialog.currentPathFolders[dirIndex][1])
763
			end
764
765
			if fileDialog.currentTab == 3 then
766
				setColors(monitor, colors.black, colors.white, colors.black, colors.white)
767
			else
768
				setColors(monitor, colors.lightGray, colors.white, colors.black, colors.white)
769
			end
770
			monitor.setCursorPos(offX + fileStart, offY + 5+i)
771
			monitor.write(string.rep(" ", width - fileStart - 2))
772
			if fileDialog.currentPathFiles[fileIndex] then
773
				if fileDialog.currentTab == 3 and fileIndex == fileDialog.fileSelected then
774
					setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
775
				end
776
				monitor.setCursorPos(offX + fileStart, offY + 5+i)
777
				monitor.write(fileDialog.currentPathFiles[fileIndex][1])
778
			end
779
		end
780
		
781
		--gui debug
782
		--monitor.setCursorPos(1,1)
783
		--monitor.write("ICur="..collectedInputsCursor.file.." IOff="..collectedInputsOffsets.file.." ISize="..collectedInputsSize.file.." IValSize="..string.len(collectedInputs.file))
784
end
785
function drawAbout(monitor)
786
		w,h = monitor.getSize()
787
		local height = 13
788
		local width = 39
789
		local offX = (w+1)/2 - (width-1)/2
790
		local offY = (h+1)/2 - (height-1)/2
791
		if monitor.isColor() then
792
			monitor.setBackgroundColor(colors.cyan)
793
		else
794
			monitor.setBackgroundColor(colors.black)
795
		end
796
		monitor.clear()
797
		for i=1, height do
798
				setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
799
				monitor.setCursorPos(offX, offY+i-1)
800
				if i == 1 or i == height then
801
						monitor.write("+")
802
						monitor.write(string.rep("-", width-2))
803
						monitor.write("+")
804
						if i == 1 then
805
								setColors(monitor, colors.black, colors.yellow, colors.black, colors.white)
806
								centerText(monitor, offY+i-1, " About TACO BETA ")
807
								setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
808
						end
809
				else
810
						setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
811
						monitor.write("|")
812
						setColors(monitor, colors.white, colors.black, colors.white, colors.black)
813
						monitor.write(string.rep(" ", width-2))
814
						setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
815
						monitor.write("|")
816
				end
817
		end
818
		drawPictureTable(monitor, logo, offX + 2, offY + 2, colours.white)
819
		setColors(monitor, colors.white, colors.orange, colors.white, colors.black)
820
		centerTextWidth(monitor, offX + 14, offY+3, width - ((offX*2) + 10), "=TACO BETA=")
821
		setColors(monitor, colors.white, colors.gray, colors.white, colors.black)
822
		centerTextWidth(monitor, offX + 14, offY+4, width - ((offX*2) + 10), "Edit with flavor!")
823
		setColors(monitor, colors.white, colors.lightGray, colors.white, colors.black)
824
		centerTextWidth(monitor, offX + 14, offY+6, width - ((offX*2) + 10), "By: da404lewzer")
825
		centerTextWidth(monitor, offX + 14, offY+8, width - ((offX*2) + 10), "TurtleScripts.com")
826
		centerTextWidth(monitor, offX + 14, offY+9, width - ((offX*2) + 10), "Project #gjdh01")
827
end
828
function drawMessage(monitor)
829
	w,h = monitor.getSize()
830
	local height = #message.body + 2 + 2 --2 for header/footer, 2 for border
831
	local width = 1
832
	for i=1, #message.body do
833
		if string.len(message.body[i])+4 > width then
834
				width = string.len(message.body[i])+4
835
		end
836
	end
837
	local footerMsg = ""
838
	for o=1, #message.footer do
839
		local item = message.footer[o][1]
840
		if selectedMessageOption == o then
841
			item = "["..item.."]"
842
		else
843
			item = " "..item.." "
844
		end
845
		if o > 1 then
846
			item = " "..item
847
		end
848
		footerMsg=footerMsg..item
849
	end
850
	if string.len(message.title)+4 > width then
851
			width = string.len(message.title)+4
852
	end
853
	if string.len(footerMsg)+4 > width then
854
			width = string.len(footerMsg)+4
855
	end
856
	local offX = (w+1)/2 - (width-1)/2
857
	local offY = (h+1)/2 - (height-1)/2
858
	for i=1, height do
859
		setColors(monitor, colors.orange, colors.black, colors.black, colors.white)
860
		monitor.setCursorPos(offX, offY+i-1)
861
		if i == 1 or i == height then
862
				monitor.write("+")
863
				monitor.write(string.rep("-", width-2))
864
				monitor.write("+")
865
				if i == 1 then
866
						setColors(monitor, colors.black, colors.yellow, colors.black, colors.white)
867
						centerText(monitor, offY+i-1, " "..message.title.." ")
868
						setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
869
				elseif i == height then
870
						setColors(monitor, colors.black, colors.white, colors.black, colors.white)
871
						centerText(monitor, offY+i-1, " "..footerMsg.." ")
872
						setColors(monitor, colors.orange, colors.black, colors.white, colors.black)
873
				end
874
		else
875
				setColors(monitor, colors.orange, colors.black, colors.black, colors.white)
876
				monitor.write("|")
877
				setColors(monitor, colors.white, colors.black, colors.white, colors.black)
878
				monitor.write(string.rep(" ", width-2))
879
				setColors(monitor, colors.orange, colors.black, colors.black, colors.white)
880
				monitor.write("|")
881
				if i-2 > 0 and i-2 <= #message.body then
882
						setColors(monitor, colors.white, colors.black, colors.white, colors.black)
883
						centerText(monitor, offY+i-1, message.body[i-2])
884
				end
885
				
886
		end
887
	end
888
end
889
function messageBox(title, bodyArr, footer)
890
	message.title = title
891
	message.body = bodyArr
892
	message.footer = footer
893
	showingMessage = true
894
end
895
local function trySaveFileAs()
896
	showFileSaveAsDialog()
897
end
898
local function stopEditor()
899
	running = false
900
end
901
local function trySaveFile()
902
	if currentFile == ""then
903
		trySaveFileAs()
904
	else
905
		saveFile(currentFile, fileLinesArr)
906
	end
907
end
908
local function trySaveFileThenNew()
909
	if currentFile == ""then
910
		trySaveFileAs()
911
	else
912
		saveFile(currentFile, fileLinesArr)
913
		if isSaved and not isChanged then
914
			newFile()
915
		end
916
	end
917
end
918
local function trySaveFileThenOpen()
919
	if currentFile == ""then
920
		trySaveFileAs()
921
	else
922
		saveFile(currentFile, fileLinesArr)
923
		if isSaved and not isChanged then
924
			showFileOpenDialog()
925
		end
926
	end
927
end
928
local function trySaveFileThenExit()
929
	if currentFile == ""then
930
		trySaveFileAs()
931
	else
932
		saveFile(currentFile, fileLinesArr)
933
		if isSaved and not isChanged then
934
			stopEditor()
935
		end
936
	end
937
end
938
local function tryExitEditor()
939
	if isSaved and not isChanged then
940
		stopEditor()
941
	else
942
		messageBox( "Exit Editor?", 
943
								{
944
									"The current file isn't saved, save it first?"
945
								}, 
946
								{{"YES", trySaveFileThenExit}, {"NO", stopEditor}, {"CANCEL", null}}
947
							)
948
	end
949
end
950
local function tryOpenFile()
951
	if isSaved and not isChanged then
952
		showFileOpenDialog()
953
	else
954
		messageBox( "Create New File..", 
955
								{
956
									"The current file isn't saved, save it first?"
957
								}, 
958
								{{"YES", trySaveFileThenOpen}, {"NO", showFileOpenDialog}, {"CANCEL", null}}
959
							)
960
	end
961
end
962
local function tryNewFile()
963
	if isSaved and not isChanged then
964
		newFile()
965
	else
966
		messageBox( "Create New File..", 
967
								{
968
									"The current file isn't saved, save it first?"
969
								}, 
970
								{{"YES", trySaveFileThenNew}, {"NO", newFile}, {"CANCEL", null}}
971
							)
972
	end
973
end
974
local function revertFile()
975
	if currentFile == "" then
976
		fileLinesArr = {""}
977
		isChanged = false
978
	else
979
		if not openFile(currentFile) then
980
			messageBox("Error!", {"Couldn't revert file!"}, {{"OK",null}})
981
		end
982
	end
983
end
984
local function tryRevertFile()
985
	messageBox( "Revert file?", 
986
							{
987
								"This cannot be done, sure?"
988
							}, 
989
							{{"YES", revertFile}, {"NO", null}}
990
						)
991
end
992
local function doFileDialogDefaultOption()
993
	local item = fileDialog.footer[1][2]
994
	if item then
995
		item()
996
	end
997
	fileDialog.selectedFooterOption = 1
998
end
999
local function doFileDialogMessageOption()
1000
	local item = fileDialog.footer[fileDialog.selectedFooterOption][2]
1001
	if item then
1002
		item()
1003
	end
1004
	fileDialog.selectedFooterOption = 1
1005
end
1006
local function doMessageOption()
1007
	local item = message.footer[selectedMessageOption][2]
1008
	if item then
1009
		item()
1010
	end
1011
	selectedMessageOption = 1
1012
end
1013
local function doMenuAction(action)
1014
		if action == "exit_app" then
1015
				tryExitEditor()
1016
		elseif action == "new_file" then
1017
				tryNewFile()
1018
		elseif action == "open_file" then
1019
				tryOpenFile()
1020
		elseif action == "revert_file" then
1021
				tryRevertFile()
1022
		elseif action == "save_file" then
1023
				trySaveFile()
1024
		elseif action == "saveas_file" then
1025
				trySaveFileAs()
1026
		elseif action == "paste_line" then
1027
				table.insert(fileLinesArr, curLine, config.clipboard)
1028
				isChanged=true
1029
		elseif action == "clone_line" then
1030
				table.insert(fileLinesArr, curLine, fileLinesArr[curLine])
1031
				isChanged=true
1032
		elseif action == "copy_line" then
1033
				config.clipboard = fileLinesArr[curLine]
1034
		elseif action == "cut_line" then
1035
				config.clipboard = fileLinesArr[curLine]
1036
				table.remove(fileLinesArr, curLine)
1037
				if #fileLinesArr == 0 then
1038
					fileLinesArr = {""}
1039
				end
1040
				isChanged=true
1041
		elseif action == "delete_line" then
1042
				table.remove(fileLinesArr, curLine)
1043
				if #fileLinesArr == 0 then
1044
					fileLinesArr = {""}
1045
				end
1046
				isChanged=true
1047
		elseif action == "perform_update" then
1048
				setColors(temp, colors.black, colors.white, colors.black, colors.white)
1049
				term.clear()
1050
				term.setCursorPos(1,1)
1051
				updateAllTheThings()
1052
				messageBox("Downloaded Latest", 
1053
										{
1054
												"Restart TACO to complete :)"
1055
										}, 
1056
										{{"OK", null}})
1057
			timer = os.startTimer(0.01)
1058
		elseif action == "show_about" then
1059
				showAboutBox = true
1060
		elseif action == "fullscreen_toggle" then
1061
				config.isFullScreen = not config.isFullScreen
1062
				checkLinePosition()
1063
				checkColPosition()
1064
		else
1065
				--show_help
1066
				--show_settings
1067
				--replace_text
1068
				--find_text
1069
				--delete_line
1070
				--paste_line
1071
				--copy_line
1072
				--cut_line
1073
				--clear_selection
1074
				--paste_selection
1075
				--cut_selection
1076
				--copy_selection
1077
				--print_file
1078
				--revert_file
1079
				--open_file
1080
				
1081
		end
1082
		selectedMenu = 1
1083
		selectedSubMenu = 1
1084
end
1085
1086
1087
loadSettings()
1088
1089
if #tArgs > 0 then
1090
	--openFile(tArgs[1])
1091
	if not openFile(addSlashIfNeededLeft(shell.resolve(getFilePath(tArgs[1])))) then
1092
		messageBox("Error!", {"Couldn't open file!"}, {{"OK",null}})
1093
	end
1094
end
1095
prepareDialog()
1096
if showFirstTimeMessage then
1097
		messageBox("Welcome to TACO BETA", 
1098
								{
1099
										"Welcome to the editor with flavor!",
1100
										"This is BETA sorry if you find bugs :(",
1101
										"",
1102
										"Presse ENTER to continue,",
1103
										"Press CONTROL to access menus :)"
1104
								}, 
1105
								{{"OK", null}})
1106
end
1107
while running do
1108
	local event, p1,p2,p3 = os.pullEvent()
1109
	if event == "mouse_scroll" then 
1110
		if not showingMessage and not showAboutBox and not inMenu then
1111
			curLine=curLine+p1
1112
			checkLinePosition()
1113
			checkColPosition()
1114
			resetBlink()
1115
		end
1116
	elseif event == "mouse_click" then 
1117
		if not showingMessage and not showAboutBox and not showingFileDialog then-- and not inMenu
1118
			local padWidth = string.len(tostring(#fileLinesArr))
1119
			local offsetY = 1
1120
			if config.isFullScreen then offsetY = 0 end
1121
			if p1 == 1 then
1122
				if p3 <= 1 then
1123
					pos = 1
1124
					prevPos = pos
1125
1126
					for i = 1, #menus do
1127
						pos = pos + string.len(menus[i].name) + 2
1128
1129
						if p2 > prevPos and p2 <= pos then
1130
							if i == selectedMenu and inMenu then
1131
								inMenu = false
1132
							else
1133
								inMenu = true
1134
								selectedMenu = i
1135
								selectedSubMenu = 1
1136
							end
1137
1138
							break
1139
						end
1140
1141
						prevpos = pos
1142
					end
1143
				end
1144
1145
				if inMenu and p3 > 1 then
1146
					menuOffset = getMenuOffset(selectedMenu)
1147
1148
					if p2 > menuOffset - 1 and p2 < menuOffset + getMenuWidth(selectedMenu) and p3 <= getMenuHeight(selectedMenu) + 1 then
1149
						items = menus[selectedMenu].items
1150
						itemCount = #items
1151
1152
						for i = 1, itemCount do
1153
							if p3 - 1 == i then
1154
								if items[i][1] == "--" then
1155
									if i >= itemCount then
1156
										if i == 1 then
1157
											selectedSubMenu = 1
1158
										else
1159
											selectedSubMenu = i - 1
1160
										end
1161
									else
1162
										selectedSubMenu = i + 1
1163
									end
1164
								else
1165
									selectedSubMenu = i
1166
									doMenuAction(menus[selectedMenu].items[selectedSubMenu][3])
1167
									inMenu = false
1168
								end
1169
							end
1170
						end
1171
					else
1172
						inMenu = false
1173
					end
1174
				elseif not inMenu and p3 > 1 then
1175
					curCol=p2-padWidth-scrollOffsetX-2
1176
					curLine=p3-offsetY-scrollOffsetY
1177
					checkLinePosition()
1178
					checkColPosition()
1179
					resetBlink()
1180
				end
1181
			end
1182
		elseif showingMessage then
1183
			height = #message.body + 4
1184
			posY = (((h + 1) / 2) - ((height - 1) / 2)) + height - 1
1185
1186
			footerWidth = 1
1187
1188
			for i = 1, #message.footer do
1189
				item = message.footer[i][1]
1190
				footerWidth = footerWidth + string.len(item) + 2
1191
1192
				if i > 1 then
1193
					footerWidth = footerWidth + 1
1194
				end
1195
			end
1196
1197
			posX = ((w + 1) / 2) - ((footerWidth - 1) / 2)	-- + 1 for space before buttons
1198
1199
			if p3 == posY then
1200
				pos = posX
1201
				prevPos = pos
1202
1203
				for i = 1, #message.footer do
1204
					pos = pos + string.len(message.footer[i][1]) + 2
1205
1206
					if p2 >= prevPos and p2 < pos then
1207
						selectedMessageOption = i
1208
						showingMessage = false
1209
						doMessageOption()
1210
						break
1211
					end
1212
1213
					pos = pos + 1
1214
					prevPos = pos
1215
				end
1216
			end
1217
		elseif showingFileDialog then
1218
			if p3 == 4 and p2 > 10 and p2 <= w - 4 then	-- File textbox
1219
				fileDialog.currentTab = 1
1220
				collectedInputsCursor.file = p2 - collectedInputsOffsets.file - 11
1221
				checkDialogLimits()
1222
			elseif p3 > 6 and p3 <= h - 3 then	-- Dir and File horizontal area
1223
				if p2 > 4 and p2 <= 16 then
1224
					fileDialog.currentTab = 2
1225
					fileDialog.dirSelected = fileDialog.dirScrollOffset + (p3 - 6)
1226
					checkDialogLimits()
1227
					fileDialog.basePath = fileDialog.currentPathFolders[fileDialog.dirSelected][2]
1228
					fileDialog.dirScrollOffset = 1
1229
					fileDialog.dirSelected = 1
1230
					prepareDialog()
1231
				elseif p2 > 17 and p2 <= w - 4 then
1232
					fileDialog.currentTab = 3
1233
					fileDialog.fileSelected = fileDialog.fileScrollOffset + (p3 - 6)
1234
					checkDialogLimits()
1235
					collectedInputs.file = fileDialog.currentPathFiles[fileDialog.fileSelected][2]
1236
				end
1237
			elseif p3 == h - 1 then
1238
				footerWidth = 1
1239
1240
				for i = 1, #fileDialog.footer do
1241
					item = fileDialog.footer[i][1]
1242
					footerWidth = footerWidth + string.len(item) + 2
1243
1244
					if i > 1 then
1245
						footerWidth = footerWidth + 1
1246
					end
1247
				end
1248
1249
				footerOffset = ((w + 1) / 2) - (footerWidth / 2)
1250
1251
				if p2 >= footerOffset and p2 <= footerOffset + footerWidth then
1252
					fileDialog.currentTab = 4
1253
				end
1254
1255
				pos = footerOffset + 1
1256
				prevPos = pos
1257
1258
				for i = 1, #fileDialog.footer do
1259
					pos = pos + string.len(fileDialog.footer[i][1]) + 2
1260
1261
					if p2 >= prevPos and p2 < pos then
1262
						fileDialog.selectedFooterOption = i
1263
						doFileDialogMessageOption()
1264
						break
1265
					end
1266
1267
					pos = pos + 1
1268
					prevPos = pos
1269
				end
1270
			end
1271
		elseif showAboutBox then
1272
			showAboutBox = false
1273
		end
1274
	elseif event == "key" then 
1275
		if showingMessage then
1276
			if p1 == keys.enter then
1277
				showingMessage = false
1278
				doMessageOption()
1279
			elseif p1 == keys.left or p1 == keys.up then
1280
				selectedMessageOption=selectedMessageOption-1
1281
				checkMessageOptionPositions()
1282
			elseif p1 == keys.right or p1 == keys.down then
1283
				selectedMessageOption=selectedMessageOption+1
1284
				checkMessageOptionPositions()
1285
			end
1286
		elseif showAboutBox then
1287
			if p1 == keys.enter then
1288
				showAboutBox = false
1289
			end
1290
		elseif showingFileDialog then
1291
			if p1 == keys.enter then
1292
				if fileDialog.currentTab == 1 then
1293
					doFileDialogDefaultOption()
1294
				elseif fileDialog.currentTab == 2 then
1295
					fileDialog.basePath = fileDialog.currentPathFolders[fileDialog.dirSelected][2]					
1296
					prepareDialog()
1297
				elseif fileDialog.currentTab == 3 then
1298
					collectedInputs.file = fileDialog.currentPathFiles[fileDialog.fileSelected][2]
1299
					fileDialog.currentTab = 4
1300
					prepareDialog()
1301
				elseif fileDialog.currentTab == 4 then
1302
					doFileDialogMessageOption()
1303
				end
1304
			elseif p1 == keys.tab then
1305
				fileDialog.currentTab=fileDialog.currentTab+1
1306
				if fileDialog.currentTab > fileDialog.currentTabMax then
1307
					fileDialog.currentTab = 1
1308
				end
1309
			elseif p1 == keys.home then
1310
				if fileDialog.currentTab == 1 then
1311
					collectedInputsCursor.file=0
1312
				end
1313
				checkDialogLimits()
1314
			elseif p1 == keys["end"] then
1315
				if fileDialog.currentTab == 1 then
1316
					collectedInputsCursor.file=string.len(collectedInputs.file)+1
1317
				end
1318
				checkDialogLimits()
1319
1320
			elseif p1 == keys.backspace then
1321
				if fileDialog.currentTab == 1 then
1322
					if collectedInputsCursor.file > 0 then
1323
						local leftSide = string.sub(collectedInputs.file, 1, collectedInputsCursor.file-1)
1324
						local rightSide = string.sub(collectedInputs.file, collectedInputsCursor.file+1)
1325
						collectedInputs.file = leftSide..rightSide
1326
						collectedInputsCursor.file=collectedInputsCursor.file-1
1327
					end
1328
				end
1329
				checkDialogLimits()
1330
			elseif p1 == keys.delete then
1331
				if fileDialog.currentTab == 1 then
1332
					if collectedInputsCursor.file <= string.len(collectedInputs.file) then
1333
						local leftSide = string.sub(collectedInputs.file, 1, collectedInputsCursor.file)
1334
						local rightSide = string.sub(collectedInputs.file, collectedInputsCursor.file+2)
1335
						collectedInputs.file = leftSide..rightSide
1336
					end
1337
				end
1338
				checkDialogLimits()
1339
			elseif p1 == keys.up or p1 == keys.left then
1340
				if fileDialog.currentTab == 1 then
1341
					collectedInputsCursor.file=collectedInputsCursor.file-1
1342
				elseif fileDialog.currentTab == 2 then
1343
					fileDialog.dirSelected=fileDialog.dirSelected-1
1344
				elseif fileDialog.currentTab == 3 then
1345
					fileDialog.fileSelected=fileDialog.fileSelected-1
1346
				elseif fileDialog.currentTab == 4 then
1347
					fileDialog.selectedFooterOption=fileDialog.selectedFooterOption-1
1348
				end
1349
				checkDialogLimits()
1350
			elseif p1 == keys.down or p1 == keys.right then
1351
				if fileDialog.currentTab == 1 then
1352
					collectedInputsCursor.file=collectedInputsCursor.file+1
1353
				elseif fileDialog.currentTab == 2 then
1354
					fileDialog.dirSelected=fileDialog.dirSelected+1
1355
				elseif fileDialog.currentTab == 3 then
1356
					fileDialog.fileSelected=fileDialog.fileSelected+1
1357
				elseif fileDialog.currentTab == 4 then
1358
					fileDialog.selectedFooterOption=fileDialog.selectedFooterOption+1
1359
				end
1360
				checkDialogLimits()
1361
			end
1362
		else
1363
			if state == "edit" then
1364
				if p1 == 29 or p1 == 157 then
1365
					inMenu = not inMenu
1366
				end
1367
				if inMenu then
1368
					if p1 == keys.up then
1369
						selectedSubMenu=selectedSubMenu-1
1370
						checkMenuPositions()
1371
						if menus[selectedMenu].items[selectedSubMenu][1] == "--" then
1372
							selectedSubMenu=selectedSubMenu-1
1373
							checkMenuPositions()
1374
						end
1375
					elseif p1 == keys.down then
1376
						selectedSubMenu=selectedSubMenu+1
1377
						checkMenuPositions()
1378
						if menus[selectedMenu].items[selectedSubMenu][1] == "--" then
1379
							selectedSubMenu=selectedSubMenu+1
1380
							checkMenuPositions()
1381
						end
1382
					elseif p1 == keys.left then
1383
						selectedSubMenu = 1
1384
						selectedMenu=selectedMenu-1
1385
						checkMenuPositions()
1386
					elseif p1 == keys.right then
1387
						selectedSubMenu = 1
1388
						selectedMenu=selectedMenu+1
1389
						checkMenuPositions()
1390
					elseif p1 == keys.enter then
1391
						doMenuAction(menus[selectedMenu].items[selectedSubMenu][3])
1392
						inMenu = false
1393
					end
1394
				else
1395
					if p1 == keys.up then
1396
						curLine=curLine-1
1397
					elseif p1 == keys.down then
1398
						curLine=curLine+1
1399
					elseif p1 == 201 then -- page up
1400
						curLine=curLine-(h-2)
1401
					elseif p1 == 209 then --page down
1402
						curLine=curLine+(h-2)
1403
					elseif p1 == keys.left then
1404
						curCol=curCol-1
1405
					elseif p1 == keys.right then
1406
						curCol=curCol+1
1407
					elseif p1 == keys.home then
1408
						curCol=0
1409
					elseif p1 == keys["end"] then
1410
						curCol=string.len(fileLinesArr[curLine])+1
1411
					elseif p1 == keys.tab then
1412
						isChanged=true
1413
						local leftSide = string.sub(fileLinesArr[curLine], 1, curCol)
1414
						local rightSide = string.sub(fileLinesArr[curLine], curCol+1)
1415
						fileLinesArr[curLine] = leftSide.."	"..rightSide
1416
						curCol=curCol+2
1417
						resetBlink()
1418
						checkLinePosition()
1419
						checkColPosition()
1420
					elseif p1 == keys.enter then
1421
						isChanged=true
1422
						if curCol == string.len(fileLinesArr[curLine]) then
1423
							curLine=curLine+1
1424
							curCol=0
1425
							table.insert(fileLinesArr, curLine, "")
1426
						elseif curCol == 0 then
1427
							table.insert(fileLinesArr, curLine, "")	
1428
							curLine=curLine+1
1429
						else										
1430
							local leftSide = string.sub(fileLinesArr[curLine], 1, curCol)
1431
							local rightSide = string.sub(fileLinesArr[curLine], curCol+1)
1432
							fileLinesArr[curLine] = leftSide
1433
							table.insert(fileLinesArr, curLine+1, rightSide)	 
1434
							curLine=curLine+1
1435
							curCol=0
1436
						end
1437
					elseif p1 == keys.backspace then
1438
						isChanged=true
1439
						if curCol > 0 then
1440
							local leftSide = string.sub(fileLinesArr[curLine], 1, curCol-1)
1441
							local rightSide = string.sub(fileLinesArr[curLine], curCol+1)
1442
							fileLinesArr[curLine] = leftSide..rightSide
1443
							curCol=curCol-1
1444
						elseif curCol == 0 and curLine > 1 then
1445
							local newCurCol = string.len(fileLinesArr[curLine-1])
1446
							fileLinesArr[curLine-1] = fileLinesArr[curLine-1] .. fileLinesArr[curLine]
1447
							table.remove(fileLinesArr, curLine)
1448
							curLine = curLine -1
1449
							curCol = newCurCol
1450
						end
1451
					elseif p1 == keys.delete then
1452
						isChanged=true
1453
						if curCol < string.len(fileLinesArr[curLine]) then
1454
							local leftSide = string.sub(fileLinesArr[curLine], 1, curCol)
1455
							local rightSide = string.sub(fileLinesArr[curLine], curCol+2)
1456
							fileLinesArr[curLine] = leftSide..rightSide
1457
						elseif curCol == string.len(fileLinesArr[curLine]) and curLine < #fileLinesArr then
1458
							fileLinesArr[curLine] = fileLinesArr[curLine] .. fileLinesArr[curLine+1]
1459
							table.remove(fileLinesArr, curLine+1)
1460
						end
1461
					end
1462
					checkLinePosition()
1463
					checkColPosition()
1464
				end					
1465
				resetBlink()
1466
			elseif state == "msg" then
1467
				if p1 == keys.enter then
1468
					state = "edit"
1469
				end 
1470
			end
1471
		end
1472
	elseif event == "char" then
1473
		if showingMessage then
1474
		elseif showAboutBox then
1475
		elseif showingFileDialog then
1476
			if fileDialog.currentTab == 1 then
1477
				local leftSide = string.sub(collectedInputs.file, 1, collectedInputsCursor.file)
1478
				local rightSide = string.sub(collectedInputs.file, collectedInputsCursor.file+1)				
1479
				collectedInputs.file=leftSide..p1..rightSide
1480
				collectedInputsCursor.file=collectedInputsCursor.file+1
1481
				checkDialogLimits()
1482
			end
1483
		else
1484
			if state == "edit" then
1485
				isChanged=true
1486
				local leftSide = string.sub(fileLinesArr[curLine], 1, curCol)
1487
				local rightSide = string.sub(fileLinesArr[curLine], curCol+1)
1488
				fileLinesArr[curLine] = leftSide..p1..rightSide
1489
				curCol=curCol+1
1490
				resetBlink()
1491
				checkLinePosition()
1492
				checkColPosition()
1493
			end
1494
		end
1495
	elseif event == "timer" and p1 == timer then
1496
		if state == "edit" then
1497
			drawScreen(term)
1498
		elseif state == "additem" then
1499
			--displayAddItem()
1500
		elseif state == "msg" then
1501
			--displayMsg(currentMessage)
1502
		end
1503
		if showingFileDialog then
1504
			drawFileDialog(term)
1505
		end
1506
		if showingMessage then
1507
			drawMessage(term)
1508
		end
1509
		if showAboutBox then
1510
			drawAbout(term)
1511
		end
1512
		timer = os.startTimer(0.01)
1513
	end
1514
	if os.clock() - lastBlinkTime > 0.5 then
1515
		lastBlinkTime = os.clock()
1516
		isBlinking = not isBlinking
1517
	end
1518
end
1519
1520
saveSettings()
1521
setColors(term, colors.black, colors.white, colors.black, colors.white)
1522
term.clear()
1523
term.setCursorPos(1,1)