1// TBT javascript extensions: rgareus 2008
2// TBT javascript prototype: Jaromil 2007
3// reference javascript typewriter documentation: F. Permadi 2002
4// GNU GPL
5
6
7function TBT() {
8  this.setRowCarriageReturn = setRowCarriageReturn;
9  this.setXhtml = setXhtml;
10  this.setSpeed = setSpeed;
11  this.startTyping = startTyping;
12  this.feed = feed;
13  var currentChar;
14  var destination;
15  var cur_x;
16  var cur_y;
17  var row;
18  var col;
19  var text;
20  var render_text;
21  var rowsize;
22  var colsize;
23  var recording;
24  var cr;
25  var cc;
26  var rowcr=0; // config option; do a CR (\r) when moving the cursor up/down
27  var xhtml=0; // html or xhtml
28  var speed=1; // time factor.
29
30  function setSpeed(s) {
31    if (s> 0.01 && s< 20) this.speed=s;
32    else speed=1.0;
33  }
34
35  function setXhtml(onoff) {
36    xhtml=onoff?true:false;
37  }
38
39  function setRowCarriageReturn(onoff) {
40    rowcr=onoff?true:false;
41  }
42
43  function startTyping(destinationParam, tbtrecord) {
44    currentChar = 0;
45    destination = destinationParam;
46    recording   = tbtrecord;
47
48    // global text positions
49    row = 0;
50    col = 0;
51    // cursor positions
52    cur_x = 0;
53    cur_y = 0;
54    // length counters
55    rowsize = 0;
56    colsize = 0;
57    cr = 0;
58    cc = 0;
59
60    // text bidimensional array
61    text = new Array();
62    text[0] = new Array();
63    // text render buffer
64    render_text = "";
65
66    setTimeout(this.feed, speed*recording[currentChar][1] );
67  }
68
69  function feed() {
70    var dest = document.getElementById(destination);
71
72    if (dest) {
73	// && dest.innerHTML)
74
75	/* TODO: handle movement keys:
76	   KEY_BACKSPACE 275, 127, 272
77	   KEY_PAGE_UP 261 ; KEY_PAGE_DOWN 262
78	   KEY_HOME 263 ; KEY_DELETE 275
79	   port the abstract_console from slw in js
80	*/
81
82	// get the next char
83	switch( recording[currentChar][0] ) {
84	case 10:  // NEWLINE
85	case 13:  // RETURN
86	    cur_y++; row++;
87	    cur_x = 0; col = 0;
88	    if(row >= text.length) {
89		text[row] = new Array();
90	    }
91	    break;
92
93	case 8: // standard ASCII BACKSPACE
94	case 127: // other low level BACKSPACE codes
95	case 272: // (APPLE BACKSPACE)
96	case 275: // (SOMETIMES!?)
97
98	    if(col > 0) // delete if not at the beginning of line
99		text[row].splice(col-1,1);
100
101	    if(cur_x > 0) {
102		cur_x--;
103		col--;
104	    } else { // backspace at the beginning of a line
105		     // move everything up one line
106		// TODO
107	    }
108	    break;
109
110	case 257: // UP
111	    if(row <= 0) break;
112	    cur_y--; row--;
113	    if (rowcr) { col=0; cur_x=0; }
114	    break;
115	case 258: // DOWN
116	    if(row >= text.length) break;
117	    cur_y++; row++;
118	    if (rowcr) { col=0; cur_x=0; }
119	    break;
120	case 259: // LEFT
121	    if(cur_x <= 0) break;
122	    cur_x--;
123	    col--;
124	    break;
125	case 260: // RIGHT
126	    //	    if(cur_x >= text[row].length) break;
127	    cur_x++;
128	    col++;
129	    break;
130
131	default:
132		if (!text[row]) text[row] = new Array();
133	    text[row].splice(col,0,recording[currentChar][0]);
134	    cur_x++; col++;
135	    break;
136	}
137
138	// RENDER TEXT
139	render_text = "";
140
141	rowsize = text.length;
142	for(cr = 0; cr < rowsize; cr++) {
143
144	    colsize = text[cr].length;
145
146	    if(cur_y == cr) { // cursor row
147
148		for(cc = 0; cc < colsize; cc++) {
149
150		    if(cur_x == cc) { // draw cursor
151			    render_text += "<u>";
152			    render_text += String.fromCharCode( text[cr][cc] );
153			    render_text += "</u>";
154		    } else // not yet on cursor
155			render_text += String.fromCharCode( text[cr][cc] );
156
157		}
158
159		// draw cursor at the end of line
160		if(cur_x >= colsize) render_text += "_";
161
162	    } else  // no need to draw the cursor
163		for(cc = 0; cc < colsize; cc++)
164		    render_text += String.fromCharCode( text[cr][cc] );
165
166
167	    // newline
168	    render_text += xhtml?"<br/>":"<br>";
169	}
170
171	// render_text += String.fromCharCode( recording[currentChar][0] );
172	dest.innerHTML = render_text;
173
174
175
176	// DOM compliant alternative:
177	//	var textNode=document.createTextNode(text);
178	//	dest.replaceChild(textNode, dest.childNodes[0]);
179
180
181
182	// go to the next entry
183	currentChar++;
184
185
186	if (currentChar >= recording.length) {
187
188	    // end of record, restart after 5 seconds
189	    currentChar=0;
190	    render_text="";
191
192	    // clear all text buffer
193	    for(cr=0; cr < text.length; cr++)
194		delete text[cr];
195	    delete text;
196
197	    // end of text
198
199	} else {
200
201	   // RECURSION IS TIME  -jrml 31jan2007
202	    setTimeout(feed, speed*recording[currentChar][1] );
203	}
204    }
205  }
206};
207//Setup VIM: ex: sw=4 ts=8 enc=utf-8 :
208