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