added Validation support
[L-seed.git] / web / js / communication.js
1 if (typeof console == "undefined") {
2     console = {
3         dir: function() { }
4                 , monitor: function() { }
5                 , debug: function() { }
6                 , profile: function() { }
7                 , log: function() { }
8                 , error: function() { }
9                 , warn: function() { }
10                 , info: function() { }
11                 , profileEnd: function() { }
12                 , unmonitor: function() { }
13     };
14 }
15 if (typeof Lseed == "undefined") {
16     Lseed = {};
17 }
18
19 Lseed.MessageCommands = {
20         RPC: 'RPC'
21         ,ContentRequest: 'ContentRequest'
22 };
23
24 Lseed.Communication = function() {
25
26         // ----- Framework -----
27         
28         this.RequestCallbacks = {};
29         
30         this.sendMessage = function (cmd, opts) {
31                 var params = {};
32                 Ext.apply(params, opts, { cmd: cmd });
33                 Ext.Ajax.request({
34                         url: 'php/communication.php',
35                         success: this.handleResponse.createDelegate(this)
36                         ,failure: function(response, opts) {
37                                 Ext.MessageBox.alert("Fehler", "Es konnte keine Verbindung zum Server hergestellt werden.")
38                                                           .setIcon(Ext.MessageBox.ERROR);
39                         }
40                         ,params: params
41                 });
42         };
43
44         this.handleResponse = function (response, opts) {
45                 Ext.MessageBox.hide();
46                 console.log("'"+response.responseText+"'");
47                 try {
48                         if (!response.responseText) {
49                                 console.error("empty answer");
50                                 return;
51                         }
52                         var obj = Ext.decode(response.responseText);
53                         var cmd = obj.cmd;
54
55                         switch (cmd) {
56                                 case 'RPC':
57                                         obj.func.CreateDelegate(this)(obj.data);
58                                         break;
59                                 case 'RPC-Response':
60                                         this.RequestCallbacks[obj.calledFunc](obj.data);
61                                         break;
62                                 case 'Message':
63                                         this.showMessage(obj.msg, obj.type);
64                                         break;
65                                 case 'Content':
66                                         this.stopWaitingForPage();
67                                         
68                                         this.showContent(obj.content, obj.contentname);
69                                         break;
70                         }
71                 } catch (e) {
72                         console.error(e);
73                 }
74         };
75         
76         this.showMessage = function (msg, type) {
77                 var title = "Unbekannte Nachricht";
78                 if (type == 'error') {
79                         title = "Fehler";
80                 } else if (type == "info") {
81                         title = "Information";
82                 }
83                 var msgbox = Ext.MessageBox.alert(title, msg);
84                 if (type == 'error') {
85                         msgbox.setIcon(Ext.MessageBox.ERROR);
86                 } else if (type == "info") {
87                         msgbox.setIcon(Ext.MessageBox.INFO);
88                 }
89         };
90         
91         this.AddCallback = function (hook, func) {
92                 this.RequestCallbacks[hook] = func;
93         };
94
95
96         // ----- Application -----
97         
98         this.showContent = function (content, contentname) {
99                 switch(contentname) {
100                         case "nav":
101                         case "adminnav":
102                                 this.loadNavigation(content);
103                                 break;
104                         default:
105                                 this.loadTab(content, contentname);
106                                 break;
107                 }
108         };
109         
110         // === LOGIN ===
111         
112         this.isLoggedInCallback = function (loggIn) {
113                 if (loggIn) {
114                         Ext.MessageBox.wait("Navigation wird geladen.", "Wird geladen...");
115                         
116                         this.sendMessage(Lseed.MessageCommands.ContentRequest, {content: 'nav'});
117                 } else {
118                         this.showLoginDialog();
119                 }
120         };
121         
122         this.AuthCallback = function (success) {
123                 if (success) {
124                         Ext.MessageBox.wait("Navigation wird geladen.", "Wird geladen...");
125                         
126                         this.sendMessage(Lseed.MessageCommands.ContentRequest, {content: 'nav'});
127                 } else {
128                         this.showLoginDialog();
129                         this.showMessage(
130                                 "Es trat ein Fehler beim einloggen auf. Bitte überprüfen sie ihre eingaben und versuchen sie es erneut.", 
131                                 "error");
132                 }
133         };
134
135         this.showLoginDialog = function () {
136                 var loginDialog = Ext.getCmp("loginDialog");
137                 if (!loginDialog) {
138                         loginDialog = new Ext.Window({
139                                 id: 'loginDialog'
140                                 ,title: 'Login'
141                                 ,modal: true
142                                 ,closable: false
143                                 ,tbar: ['->',{
144                                         text: 'Register'
145                                         ,icon: 'img/icons/user_add.png'
146                                         ,cls: 'x-btn-text-icon'
147                                         ,handler: function() {
148                                                 loginDialog.hide();
149                                                 this.showRegisterDialog();
150                                         }.createDelegate(this)
151                                 }]
152                                 ,items: [{
153                                         id: 'loginDialogForm'
154                                         ,xtype: 'form'
155                                         ,labelWidth: 75
156                                         ,bodyStyle:'padding:5px 5px 0'
157                                         ,width: 350
158                                         ,defaults: {
159                                                 width: 230
160                                                 ,labelStyle: 'padding-right:5px'
161                                         }
162                                         ,defaultType: 'textfield'
163                                         ,items: [{
164                                                 id: 'loginDialogFormUsername'
165                                                 ,fieldLabel: 'Benutzername'
166                                                 ,name: 'username'
167                                                 ,allowBlank:false
168                                         },{
169                                                 id: 'loginDialogFormPassword'
170                                                 ,fieldLabel: 'Password'
171                                                 ,name: 'password'
172                                                 ,inputType: 'password'
173                                                 ,allowBlank:false
174                                         }]
175                                         ,buttons: [{
176                                                 text: 'OK'
177                                                 ,handler: this.login.createDelegate(this)
178                                         }]
179                                 }]
180                         });
181                 }
182                 
183                 loginDialog.show();
184         };
185         
186         this.login = function() {
187                 var cmpUser = Ext.getCmp('loginDialogFormUsername');
188                 var cmpPw = Ext.getCmp('loginDialogFormPassword');
189                 if (cmpUser && cmpUser.isValid() && 
190                     cmpPw && cmpPw.isValid()) {
191                         var user = cmpUser.getValue();
192                         var pw = cmpPw.getValue();
193                         pw = MD5(pw);
194                         Ext.MessageBox.wait("Authentifiziere.", "Wird geladen...");
195                         
196                         this.sendMessage(Lseed.MessageCommands.RPC, { func: 'Auth', user: user, pw: pw });
197                         this.hideLoginDialog();
198                 } else {
199                         this.showMessage("Ungültige Eingabe. Bitte überprüfen.", "error");
200                 }
201         };
202         
203         this.logout = function() {
204                 Ext.MessageBox.wait("Deauthentifiziere.", "Wird geladen...");
205                 
206                 this.sendMessage(Lseed.MessageCommands.RPC, { func: 'Logout' });
207                 this.clearNavigation();
208                 this.closeAllTabs();
209                 this.showLoginDialog();
210         };
211
212         this.hideLoginDialog = function () {
213                 var cmp = Ext.getCmp('loginDialog');
214                 if (cmp) {
215                         cmp.hide();
216                 } else {
217                         console.error("Lseed.Communication.hideLoginDialog: loginDialog couldn't be found");
218                 }
219         };
220         
221         // === REGISTER ===
222
223         this.showRegisterDialog = function () {
224                 var registerDialog = Ext.getCmp("registerDialog");
225                 if (!registerDialog) {
226                         registerDialog = new Ext.Window({
227                                 id: 'registerDialog'
228                                 ,title: 'Register'
229                                 ,modal: true
230                                 ,closable: true
231                                 ,listeners: {
232                                         close: this.showLoginDialog
233                                 }
234                                 ,items: [{
235                                         id: 'registerDialogForm'
236                                         ,xtype: 'form'
237                                         ,labelWidth: 75
238                                         ,bodyStyle:'padding:5px 5px 0'
239                                         ,width: 350
240                                         ,defaults: {
241                                                 width: 230
242                                                 ,labelStyle: 'padding-right:5px'
243                                         }
244                                         ,defaultType: 'textfield'
245                                         ,items: [{
246                                                 id: 'registerDialogFormUsername'
247                                                 ,fieldLabel: 'Benutzername'
248                                                 ,name: 'username'
249                                                 ,allowBlank:false
250                                         },{
251                                                 id: 'registerDialogFormPassword'
252                                                 ,fieldLabel: 'Password'
253                                                 ,name: 'password'
254                                                 ,inputType: 'password'
255                                                 ,allowBlank:false
256                                         },{
257                                                 id: 'registerDialogFormPasswordRepeat'
258                                                 ,fieldLabel: 'Password Wiederholung'
259                                                 ,name: 'passwordRepeat'
260                                                 ,inputType: 'password'
261                                                 ,allowBlank:false
262                                         }]
263                                         ,buttons: [{
264                                                 text: 'Register'
265                                                 ,handler: this.register.createDelegate(this)
266                                         },{
267                                                 text: 'Cancel'
268                                                 ,handler: function() {
269                                                         this.hideRegisterDialog();
270                                                         this.showLoginDialog();
271                                                 }.createDelegate(this)
272                                         }]
273                                 }]
274                         });
275                 }
276                 
277                 registerDialog.show();
278         };
279
280         this.hideRegisterDialog = function () {
281                 var cmp = Ext.getCmp('registerDialog');
282                 if (cmp) {
283                         cmp.hide();
284                 } else {
285                         console.error("Lseed.Communication.hideRegisterDialog: registerDialog couldn't be found");
286                 }
287         };
288         
289         this.register = function() {
290                 var cmpUser = Ext.getCmp('registerDialogFormUsername');
291                 var cmpPw = Ext.getCmp('registerDialogFormPassword');
292                 var cmpPwRepeat = Ext.getCmp('registerDialogFormPasswordRepeat');
293                 if (cmpUser && cmpUser.isValid() && 
294                     cmpPw && cmpPw.isValid() && 
295                     cmpPwRepeat && cmpPwRepeat.isValid()) {
296                         var user = cmpUser.getValue();
297                         var pw = cmpPw.getValue();
298                         var pwRepeat = cmpPwRepeat.getValue();
299                         if (pw == pwRepeat) {
300                                 pw = MD5(pw);
301                                 Ext.MessageBox.wait("Registriere.", "Wird geladen...");
302
303                                 this.sendMessage(Lseed.MessageCommands.RPC, { func: 'Register', user: user, pw: pw });
304                                 this.hideRegisterDialog();
305                         } else {
306                                 this.showMessage("Passwörter stimmen nicht überein. Bitte korrigieren.", "error");
307                         }
308                 } else {
309                         this.showMessage("Ungültige Eingabe. Bitte überprüfen.", "error");
310                 }
311         };
312         
313         this.RegisterCallback = function (data) {
314                 if (data.success) {
315                         Ext.MessageBox.wait("Navigation wird geladen.", "Wird geladen...");
316                         
317                         this.sendMessage(Lseed.MessageCommands.ContentRequest, {content: 'nav'});
318                 } else {
319                         this.showRegisterDialog();
320                         this.showMessage(
321                                 data.msg, 
322                                 "error");
323                 }
324         };
325         
326         // === Plant Managerment ===
327         
328         this.GetPlantList = function() {
329                 Ext.MessageBox.wait("Pflanzen werden geladen.", "Wird geladen...");
330                 
331                 this.sendMessage(Lseed.MessageCommands.RPC, { func: 'GetPlantList' });
332         };
333         
334         this.GetPlantListCallback = function(data) {
335                 var grid = Ext.getCmp("plantlistgrid");
336                 if (grid) {
337                         grid.store.loadData(data.list);
338                 } else {
339                         console.error("Lseed.Communication.GetPlantList: 'plantlistgrid' could not be found.");
340                 }
341         }
342         
343         this.loadNavigation = function(content) {
344                 var cmp = Ext.getCmp('navTree');
345                 if (cmp) {
346                         cmp.setRootNode(content);
347                 } else {
348                         console.error("Lseed.Communication.loadNavigation: 'navTree' does not exist.");
349                 }
350         };
351         
352         this.clearNavigation = function() {
353                 var cmp = Ext.getCmp('navTree');
354                 if (cmp) {
355                         cmp.setRootNode(new Ext.tree.AsyncTreeNode({
356                                 expanded: true
357                                 ,children: [{
358                                         text: 'Start'
359                                         ,leaf: true
360                                 }]
361                         }));
362                 } else {
363                         console.error("Lseed.Communication.clearNavigation: 'navTree' does not exist.");
364                 }
365         };
366         
367         this.closeAllTabs = function() {
368                 var cmp = Ext.getCmp('contentTabPanel');
369                 if (cmp) {
370                         var elem = cmp.get(0);
371                         cmp.removeAll();
372                         cmp.add(elem);
373                 } else {
374                         console.error("Lseed.Communication.clearNavigation: 'navTree' does not exist.");
375                 }
376         };
377         
378         this.loadTab = function (content, name) {
379                 var cmp = Ext.getCmp("contentTabPanel");
380                 if (cmp) {
381                         cmp.add(content);
382                         this.activateTab(name)
383                 } else {
384                         console.error("Lseed.Communication.showTab: 'contentTabPanel' does not exist.");
385                 }
386         };
387         
388         this.getTab = function (tabname) {
389                 var result = null;
390                 
391                 var cmp = Ext.getCmp("contentTabPanel");
392                 if (cmp) {
393                         result = cmp.findById("ContentPanel_"+tabname);
394                 } else {
395                         console.error("Lseed.Communication.activateTab: 'contentTabPanel' does not exist.");
396                 }
397                 
398                 return result;
399         };
400         
401         this.activateTab = function (tabname) {
402                 var done = false;
403                 
404                 var tab = this.getTab(tabname);
405                 
406                 if (tab) {
407                         var cmp = Ext.getCmp("contentTabPanel");
408                         if (cmp) {
409                                 cmp.setActiveTab(tab);
410                                 done = true;
411                         } else {
412                                 console.error("Lseed.Communication.activateTab: 'contentTabPanel' does not exist.");
413                         }
414                 }
415                 
416                 return done;
417         };
418         
419         this.showTab = function (tabname) {
420                 var done = false;
421                 
422                 done = this.activateTab(tabname);
423                         
424                 if (!done) {
425                         this.waitForPage();
426                         
427                         this.sendMessage(Lseed.MessageCommands.ContentRequest, {content: tabname});
428                 }
429         };
430         
431         this.waitForPage = function() {
432                 var cmp = Ext.getCmp("loadPageProgressbar");
433                 if (cmp) {
434                         cmp.show();
435                         cmp.wait({
436                                 interval: 200,
437                                 increment: 15,
438                                 text: 'Lädt...'
439                         });
440                 } else {
441                         console.error("Lseed.Communication.waitForPage: loadPageProgressbar is not defined.");
442                 }
443         };
444         
445         this.stopWaitingForPage = function() {
446                 var cmp = Ext.getCmp("loadPageProgressbar");
447                 if (cmp) {
448                         cmp.updateText("");
449                         cmp.reset();
450                 } else {
451                         console.error("Lseed.Communication.stopWaitingForPage: loadPageProgressbar is not defined.");
452                 }
453         };
454
455         this.Init = function(editor) {
456                 Ext.MessageBox.wait("Programmeinstellungen werden geladen.", "Wird geladen...");
457
458                 this.AddCallback("IsLoggedIn", this.isLoggedInCallback.createDelegate(this));
459                 this.AddCallback("Auth", this.AuthCallback.createDelegate(this));
460                 this.AddCallback("Register", this.RegisterCallback.createDelegate(this));
461                 this.AddCallback("GetPlantList", this.GetPlantListCallback.createDelegate(this));
462                 
463                 this.AddCallback("SavePlant", editor.SaveCallback.createDelegate(editor));
464                 this.AddCallback("DeletePlant", editor.DeleteCallback.createDelegate(editor));
465                 this.AddCallback("ValidatePlant", editor.CheckSyntaxCallback.createDelegate(editor));
466                 
467                 this.sendMessage(Lseed.MessageCommands.RPC, {func: 'IsLoggedIn'});
468         };
469 };
470
471
472 Lseed.Editor = function() {
473         this.CurrentPlant = {
474                 Name: ''
475                 ,Definition: ''
476         };
477         
478         this.Save = function(plant) {
479                 
480                 communication.sendMessage(Lseed.MessageCommands.RPC, { 
481                         func: 'SavePlant'
482                         ,name: plant.data.Name
483                         ,code: plant.data.Code
484                 });
485         };
486         
487         this.SaveCallback = function(data) {
488                 if (data.success) {
489                         communication.showMessage("Erfolgreich gespeichert.", "info");
490                 } else {
491                         communication.showMessage(data.msg, "error");
492                 }
493         };
494         
495         this.Test = function(plant, callback) {
496                 communication.showMessage("Diese Funktion ist leider momentan nicht verfügbar", "error");
497         };
498         
499         this.TestCallback = function() {
500         };
501         
502         this.CheckSyntaxCallback = null;
503         this.CheckSyntax = function(plant, callback) {
504                 this.CheckSyntaxCallback = callback;
505                 
506                 communication.sendMessage(Lseed.MessageCommands.RPC, { 
507                         func: 'ValidatePlant'
508                         ,code: plant.data.Code
509                 });
510         };
511         
512         this.CheckSyntaxCallback = function(data) {
513                 if (!data.valid) {
514                         if (this.CheckSyntaxCallback != null) {
515                                 this.CheckSyntaxCallback(data);
516                         } else {
517                                 console.error("Lseed.Editor.CheckSyntaxCallback: no Callback given.");
518                         }
519                 } else {
520                         console.info("Syntax is Valid.");
521                 }
522         };
523         
524         this.Delete = function(plant) {
525                 communication.sendMessage(Lseed.MessageCommands.RPC, { 
526                         func: 'DeletePlant'
527                         ,id: plant.data.ID
528                 });
529         };
530         
531         this.DeleteCallback = function(data) {
532                 if (!data.success) {
533                         communication.showMessage("Diese Pflanze konnte leider nicht gelöscht werden.", "error");
534                 }
535                 communication.GetPlantList();
536         };
537         
538         this.GetStartFromField = function(field, row, column) {
539                 var result = 0;
540                 var content = field.getValue();
541                 var lines = content.split("\n");
542                 if (lines.length >= row) {
543                         for (var i=0; i<row; i++) {
544                                 result += lines[i].length + 1;
545                         }
546                 }
547                 result += column;
548                 
549                 console.info("error in row: " + row + " column: " + column + " at: " + result);
550                 
551                 return result;
552         };
553 };
554
555 Lseed.Plant = Ext.data.Record.create([{
556         name: 'ID'
557         ,type: 'int'
558 }, {
559         name: 'Name'
560         ,type: 'string'
561 }, {
562         name: 'Code'
563         ,type: 'string'
564 }]);
565