Imports System.IO
Imports System.Text

Module mainModule

    Private Function ReadAFile(ByVal FileName As String, ByVal Encode As Encoding) As String
        Try
            If My.Computer.FileSystem.FileExists(FileName) Then
                Dim fileReader As New StreamReader(FileName, Encode)
                Dim R As String = fileReader.ReadToEnd()
                fileReader.Close()
                Return R
            Else
                Console.WriteLine("File not found.")
                Return ""
            End If
        Catch ex As Exception
            Console.WriteLine("{0}", ex.Message)
            Return ""
        End Try
    End Function

    Sub Main()
        Dim CurrentLine As Integer = 0, cursorLine As Integer = 0, perviousPositions As New List(Of Integer)
        Dim undoID As Integer = 0
        Dim Lines As New List(Of String)
        Dim EncodeID As Integer = Encoding.Default.CodePage
        If My.Application.CommandLineArgs.Count > 0 AndAlso File.Exists(My.Application.CommandLineArgs(0)) Then
            Console.Title = "Loading"
            Console.WriteLine("Current Encoding Page is {0}", Encoding.GetEncoding(EncodeID).EncodingName)
            Console.WriteLine("Reading File {0}...", My.Computer.FileSystem.GetName(My.Application.CommandLineArgs(0)))
            Lines.AddRange(ReadAFile(My.Application.CommandLineArgs(0), Encoding.GetEncoding(EncodeID)).Replace(vbCrLf, vbLf).Replace(vbCr, vbLf).Split(vbLf))
            Console.Title = My.Computer.FileSystem.GetName(My.Application.CommandLineArgs(0))
            perviousPositions.Add(0)
            undoID = 0
            Do
                Try
                    Console.WriteLine("Line #{0}", CurrentLine)
                    For i As Integer = CurrentLine To Lines.Count - 1
                        If Console.CursorTop >= Console.WindowHeight - 1 Then
                            cursorLine = i
                            Exit For
                        End If
                        Console.WriteLine("{0}", Lines(i))
                    Next
                    Select Case Console.ReadKey.Key
                        Case ConsoleKey.Escape
                            Exit Sub
                        Case ConsoleKey.Spacebar, ConsoleKey.PageDown
                            CurrentLine = cursorLine
                            perviousPositions.Add(CurrentLine)
                            undoID = perviousPositions.Count - 1
                        Case ConsoleKey.PageUp
                            If CurrentLine > Console.WindowHeight Then CurrentLine -= Console.WindowHeight Else CurrentLine = 0
                            perviousPositions.Add(CurrentLine)
                            undoID = perviousPositions.Count - 1
                        Case ConsoleKey.DownArrow
                            If CurrentLine < Lines.Count - 1 Then CurrentLine += 1
                            perviousPositions.Add(CurrentLine)
                            undoID = perviousPositions.Count - 1
                        Case ConsoleKey.UpArrow
                            If CurrentLine > 0 Then CurrentLine -= 1
                            perviousPositions.Add(CurrentLine)
                            undoID = perviousPositions.Count - 1
                        Case ConsoleKey.Backspace
                            If perviousPositions.Count > 1 Then
                                cursorLine = perviousPositions(undoID)
                                If undoID > 0 Then undoID -= 1
                            End If
                        Case ConsoleKey.Home
                            CurrentLine = 0
                            perviousPositions.Add(CurrentLine)
                            undoID = perviousPositions.Count - 1
                        Case ConsoleKey.End
                            CurrentLine = Lines.Count - 1 - Console.WindowHeight
                            perviousPositions.Add(CurrentLine)
                            undoID = perviousPositions.Count - 1
                        Case ConsoleKey.Tab
                            If perviousPositions.Count > 1 Then
                                If undoID < perviousPositions.Count - 1 Then undoID += 1
                                cursorLine = perviousPositions(undoID)
                            End If
                        Case ConsoleKey.Enter
                            Console.Write("{0}", ">")
                            Dim sTextSplit() As String = Console.ReadLine.ToLower.Split(" ")
                            Select Case sTextSplit(0)
                                Case "goto"
                                    CurrentLine = CInt(sTextSplit(1))
                                    perviousPositions.Add(CurrentLine)
                                    undoID = perviousPositions.Count - 1
                                Case "encode"
                                    EncodeID = CInt(sTextSplit(1))
                                    Console.WriteLine("Encoding switch to {0}", Encoding.GetEncoding(EncodeID).EncodingName)
                                    GoTo reload
                                Case "reload"
reload:                             Lines.Clear()
                                    Lines.AddRange(ReadAFile(My.Application.CommandLineArgs(0), Encoding.GetEncoding(EncodeID)).Replace(vbCrLf, vbLf).Replace(vbCr, vbLf).Split(vbLf))
                                    perviousPositions.Clear()
                                    perviousPositions.Add(0)
                                    undoID = 0
                            End Select
                    End Select
                    Console.Clear()
                Catch ex As Exception
                    Console.WriteLine("{0}", ex.Message)
                End Try
            Loop
        End If
    End Sub

End Module
