Initial commit
[Nebula.git] / TextDocument.cs
1 using System;
2 using System.Collections;
3 using System.IO;
4
5 public struct Cursor {
6         private int _x;
7         private int _y;
8
9         public Cursor(int x, int y) {
10                 _x = x;
11                 _y = y;
12         }
13
14         public int x {
15                 get {
16                         return _x;
17                 }
18                 set {
19                         if (value < 0) _x = 0;
20                         else _x = value;
21                 }
22         }
23
24         public int y {
25                 get {
26                         return _y;
27                 }
28                 set {
29                         if (value < 0) _y = 0;
30                         else _y = value;
31                 }
32         }
33 }
34
35 public class TextArray {
36         private ArrayList lines;
37
38         public TextArray() {
39                 lines = new ArrayList();
40                 lines.Add("");
41         }
42
43         public TextArray(string filename) {
44                 lines = new ArrayList();
45                 StreamReader file;
46                 string line;
47
48                 file = new StreamReader(filename);
49                 while ((line = file.ReadLine()) != null) {
50                         lines.Add(line);
51                 }
52         }
53
54         public ArrayList Lines {
55                 get {
56                         return lines;
57                 }
58         }
59
60         public void Insert(int x, int y, char c) {
61                 while (lines.Count < y+1)
62                         lines.Add("");
63                 string s = (string)lines[y];
64
65                 if (x >= s.Length && (c == ' ' || c == '\t')) return;
66                 if (x > s.Length) {
67                         lines[y] = s.PadRight(x) + c;
68                 } else if (x <= s.Length) {
69                         lines[y] = s.Insert(x, new string(c, 1));
70                 }
71         }
72
73         public void Delete(int x, int y) {
74                 if (y >= lines.Count) return;
75
76                 string s = (string)lines[y];
77                 if (x >= s.Length) return;
78
79                 if (s.Length == 0 && x == 0) {
80                         lines.RemoveAt(y);
81                 } else {
82                         s.Remove(x, 1);
83                 }
84         }
85
86         public void Backspace(int x, int y) {
87                 if (x == 0 && y == 0) return;
88                 if (y >= lines.Count) return;
89
90                 string s = (string)lines[y];
91                 if (x > s.Length) return;
92
93                 if (s.Length == 0 && x == 0) {
94                         lines.RemoveAt(y);
95                 } else if (x == 0 && y > 0) {
96                         lines.RemoveAt(y);
97                         lines[y-1] += s;
98                 } else {
99                         lines[y] = s.Remove(x-1, 1);
100                 }
101         }
102
103         public void Newline(int x, int y) {
104                 if (y >= lines.Count) return;
105                 string s = (string) lines[y];
106                 if (x < s.Length) {
107                         lines[y] = s.Substring(0, x);
108                         lines.Insert(y + 1, s.Substring(x));
109                 } else {
110                         if (y == lines.Count - 1) return;
111                         lines.Insert(y + 1, "");
112                 }
113         }
114
115         public int LineLength(int y) {
116                 if (y >= lines.Count) return 0;
117                 return ((string)lines[y]).Length;
118         }
119 }
120
121 public class TextDocument {
122         private TextArray text;
123         public Cursor cursor;
124
125         public ArrayList Lines {
126                 get {
127                         return text.Lines;
128                 }
129         }
130
131         public TextDocument() {
132                 text = new TextArray();
133         }
134
135         public TextDocument(string filename) {
136                 text = new TextArray(filename);
137         }
138
139         public void MoveCursor(Gdk.Key k) {
140                 switch(k) {
141                 case Gdk.Key.Up:
142                         cursor.y--;
143                         break;
144                 case Gdk.Key.Down:
145                         cursor.y++;
146                         break;
147                 case Gdk.Key.Left:
148                         cursor.x--;
149                         break;
150                 case Gdk.Key.Right:
151                         cursor.x++;
152                         break;
153                 case Gdk.Key.End:
154                         cursor.x = text.LineLength(cursor.y);
155                         break;
156                 case Gdk.Key.Home:
157                         cursor.x = 0;
158                         break;
159                 }
160         }
161
162         public void AddChar(int c) {
163                 c = c & 0xFF;
164                 if (c > 128) return;
165
166                 switch(c) {
167                 case 8:
168                         int l = 0;
169                         if (cursor.y > 0) l = text.LineLength(cursor.y-1);
170                         text.Backspace(cursor.x, cursor.y);
171                         if (cursor.x == 0) {
172                                 cursor.y--;
173                                 if (cursor.y >= text.Lines.Count) return;
174                                 cursor.x = l;
175                         } else {
176                                 cursor.x--;
177                         }
178                         break;
179                 case 13:
180                         text.Newline(cursor.x, cursor.y);
181                         cursor.x = 0;
182                         cursor.y++;
183                         break;
184                 default:
185                         text.Insert(cursor.x, cursor.y, (char)c);
186                         cursor.x++;
187                         break;
188                 }
189         }
190 }