1/**
2 * String manipulation function similar to
3 * Ruby's and pythons "prettytables_repeat" build in functions.
4 * @author szsk (http://snipplr.com/users/szsk/)
5 **/
6function getCharWidth(str){
7    var bytesCount = 0;
8    for (var i = 0; i < str.length; i++) {
9        var c = str.charAt(i);
10        if (/^[\u0000-\u00ff]$/.test(c)) {  //match ascii
11            bytesCount += 1;
12        } else { // assume all other chars has 2 ascii char width
13            bytesCount += 2;
14        }
15    }
16    return bytesCount;
17}
18function prettytables_repeat(text,num) {
19	for( var i = 0, buf = ""; i < num; i++ ){
20		buf += text;
21	}
22	return buf;
23}
24
25// this function counts the spaces in front and behind a given text, returning an array with these two counts
26function prettytables_count_spaces(text) {
27  var a=0, b=0, leading=true;
28  for (var i=0; i < text.length; i++) {
29    if (text.substr(i,1)==' ') a++; else break;
30  }
31  for (var i=text.length-1; i >= 0; i--) {
32    if (text.substr(i,1)==' ') b++; else break;
33  }
34  return [a,b];
35}
36
37
38/**
39 * String manipulation function similar to
40 * Ruby's and pythons "center" build in functions.
41 * @author szsk (http://snipplr.com/users/szsk/)
42 **/
43function prettytables_strcenter (text, width) {
44     var txt_len = getCharWidth(text);
45     var padding = " ";
46     if( txt_len < width ) {
47          var len = width - txt_len;
48          var remain = ( len % 2 === 0 ) ? "" : padding;
49          var pads = prettytables_repeat(padding, parseInt(len / 2, 10));
50          return pads + text + pads + remain;
51     }
52     else{
53          return text;
54     }
55}
56
57
58/** Table representation object.
59 * @author Constantinos Xanthopoulos <conx@xanthopoulos.info>
60**/
61function prettytable()
62{
63	this.orig_table = [];
64	this.table =  [];
65	this.map = [];
66
67	/**
68	 * Table parser function
69	 *
70	 **/
71	this.parse =  function(text){
72		this.orig_table = [];
73		this.map = [];
74		this.table = [];
75
76		var lines =  text.split(/\n/);
77		for (var i=0;i<lines.length;i++){
78			if (lines[i] !== ""){
79				var c =[];
80				var mr = [];
81				var t = this.encode(lines[i]);
82				var s;
83				if (t.match(/^[\^|]/)){
84					while (t.length != '0'){
85						s = t.match(/^[\^|]+/);
86						mr.push(s[0]);
87						t = t.substr(s[0].length);
88						t = t.replace(/^[\n ]+/,"");
89						if (t.length != 0){
90							s = t.match(/^([^|\^]*)[\^|]/);
91							t = t.substr(s[1].length);
92							s = s[1].replace(/^[ ]+/,"");
93							s = s.replace(/[ ]+$/,"");
94							c.push(s);
95						}
96					}
97					this.map.push(mr);
98					this.table.push(c);
99					// original headings without trimming (for alignment)
100					t = this.encode(lines[i]);
101					c = [];
102					while (t.length != '0'){
103						s = t.match(/^[\^|]+/);
104						t = t.substr(s[0].length);
105						t  = t.replace(/^[\n]+/,"");
106						if (t.length != 0){
107							s = t.match(/^([^|\^]*)[\^|]/);
108							t = t.substr(s[1].length);
109							s = s[1];
110							c.push(s);
111						}
112					}
113					this.orig_table.push(c);
114				}
115				else{
116					alert(LANG.plugins.prettytables.not_a_table);
117					return(null);
118				}
119			}
120		}
121		return(this);
122	};
123
124	/**
125	 * Helper function that replaces certain non table uses of
126	 * the ^ and | symbols.
127	 * @author Constantinos Xanthopoulos <conx@xanthopoulos.info>
128	 **/
129	this.encode =  function(line){
130		line = line.replace(/[%]{2}[|][%]{2}/g, "%%!@#1#@!%%");
131		line = line.replace(/[%]{2}[^][%]{2}/g, "%%!@#2#@!%%");
132		line = line.replace(/([\[]{2}[^\]]*)[|]([^\]]*[\]]{2})/g, "$1!@#1#@!$2");
133		line = line.replace(/([\{]{2}[^\}]*)[|]([^\}]*[\}]{2})/g, "$1!@#1#@!$2");
134		return line
135	};
136
137	/** Invert the replacements made by encode.
138	 * @author Constantinos Xanthopoulos <conx@xanthopoulos.info>
139	 *
140	 **/
141	this.decode =  function(){
142		for (var i=0;i<this.table.length;i++){
143			for (var j=0;j<this.table[i].length;j++){
144				t = this.table[i][j].replace(/[!][@][#][1][#][@][!]/g,"|");
145				this.table[i][j] = t.replace(/[!][@][#][2][#][@][!]/g,"^");
146			}
147		}
148	};
149
150	/**
151	 * Generate formated table
152	 * @author ConX <conx@xanthopoulos.info>
153         **/
154	this.generate =  function(){
155		var r = "";
156		var colsize = new Array(this.table[0].length);
157		this.decode();
158		for (i=0;i<colsize.length;i++){
159			colsize[i] = 0;
160		}
161
162		for (i=0;i<this.table.length;i++){
163			for (j=0;j<this.table[i].length;j++){
164				if (getCharWidth(this.table[i][j]) > colsize[j]){
165					colsize[j] = getCharWidth(this.table[i][j]);
166				}
167			}
168		}
169
170		var spaces=[];
171		for (i=0;i<this.table.length;i++){
172			for (j=0;j<this.table[i].length;j++){
173				r = r + this.map[i][j];
174
175				// left, right or center align?
176				spaces = prettytables_count_spaces(this.orig_table[i][j]);
177				if (spaces[0] >  1 && spaces[1] >  1) r = r + prettytables_strcenter(this.table[i][j],colsize[j]+4); // center
178				if (spaces[0] >  1 && spaces[1] <= 1) r = r + prettytables_repeat(' ',colsize[j]-getCharWidth(this.table[i][j])+3) + this.table[i][j] + ' '; // right
179				if (spaces[0] <= 1) r = r + ' ' + this.table[i][j] + prettytables_repeat(' ',colsize[j]-getCharWidth(this.table[i][j])+3); // left
180			}
181			if (i < this.table.length-1){
182				r = r + this.map[i][j] +"\n";
183			}
184			else{
185				r = r + this.map[i][j];
186			}
187
188		}
189		return r;
190	};
191};
192
193
194/**
195 * Button action for prettytables
196 *
197 * @author Constantinos Xanthopoulos <conx@xanthopoulos.info>
198 */
199function addBtnActionPrettytables($btn, props, edid, id){
200	$btn.click(function(){
201			var selection = DWgetSelection(jQuery('#'+edid)[0]);
202			if(selection.getLength()){
203				var sample = fixtxt(selection.getText());
204				opts = {nosel: true};
205				var pt = new prettytable();
206				pt.parse(sample);
207				if (pt !== null){
208					pasteText(selection,pt.generate(),opts);
209				}
210			}
211			else{
212				alert(LANG.plugins.prettytables.no_selection);
213			}
214
215		});
216	return true;
217}
218