Added MD5 encoding methods
[ajatus.git] / js / ajatus.document.js
blob90639c67e6ba45c84220d4a0a410e65582fa2107
1 /*
2  * This file is part of
3  *
4  * Ajatus - Distributed CRM
5  * @requires jQuery v1.2.1
6  * 
7  * Copyright (c) 2007 Jerry Jalava <jerry.jalava@gmail.com>
8  * Copyright (c) 2007 Nemein Oy <http://nemein.com>
9  * Website: http://ajatus.info
10  * Licensed under the GPL license
11  * http://www.gnu.org/licenses/gpl.html
12  * 
13  */
15 (function($){
17     $.ajatus.document = function(doc, check_metadata, check_schema) {
18         if (typeof check_metadata == 'undefined') {
19             var check_metadata = true;
20         }
21         if (typeof check_schema == 'undefined') {
22             var check_schema = false;
23         }
24         
25         // console.log("Check schema: "+check_schema);
26         // console.log("Check metadata: "+check_metadata);
27                 
28         var self = this;
29         this.ready_doc = {};
30         
31         $.each(doc, function(i,n){
32             if (   (i == '_id' && n != '')
33                 || i == 'id' && n != '') {
34                 self.ready_doc['_id'] = n;
35             } else if (i == '_rev' && n != '') {
36                 self.ready_doc[i] = n;
37             } else if (i == 'key' && n != '') {
38                 self.ready_doc[i] = n;
39             } else if (i == 'value' && n != '') {
40                 self.ready_doc[i] = n;
41             }
42         });
43         
44         if (typeof this.ready_doc['value'] == 'undefined') {
45             $.ajatus.debug("Error: Document didn't have value field defined!", "ajatus.document");            
46             return this.ready_doc;
47         }
48         
49         if (check_metadata) {
50             if (! this.ready_doc.value.metadata) {
51                 this.add_metadata();
52             } else {
53                 this.check_metadata();
54             }
55         }
57         if (! $.ajatus.preferences.client.content_types[this.ready_doc.value._type]) {
58             this.ready_doc.value._type = 'note';
59         }
61         if (check_schema) {
62             this.check_schema();
63         }
64         
65         this.prepare_doc_title();
66         
67         return this.ready_doc;
68     }
69     $.extend($.ajatus.document.prototype, {
70         check_schema: function() {
71             var self = this;
72             var type = $.ajatus.preferences.client.content_types[this.ready_doc.value._type];
73             var changed = false;
74             var new_schema_parts = {};
76             $.each(type.original_schema, function(k,si){
77                 // console.log("self.ready_doc.value.metadata["+k+"]:"+self.ready_doc.value.metadata[k])
78                 if (typeof(self.ready_doc.value[k]) == 'undefined') {
79                     def_val = '';
80                     if (typeof si['def_val'] != 'undefined') {
81                         def_val = si['def_val'];
82                     }
83                     new_schema_parts[k] = {
84                         val: def_val,
85                         widget: si.widget
86                     };
87                     changed = true;
88                 } else {
89                     def_val = self.ready_doc.value[k].val || '';
90                     if (typeof si['def_val'] != 'undefined') {
91                         def_val = si['def_val'];
92                     }                    
93                     self.ready_doc.value[k] = $.extend({
94                         val: def_val,
95                         widget: si.widget                        
96                     }, self.ready_doc.value[k]);
97                 }
98             });
99             
100             if (changed) {
101                 // console.log("Found schema parts that need to be updated:");
102                 // console.log(new_schema_parts);
103                 self._fix_doc_schema(new_schema_parts);
104             }            
105         },
106         _fix_doc_schema: function(new_parts) {
107             // console.log("FIX SCHEMA:");
108             // console.log(new_parts);
109             var _self = this;
111             doc = _self.ready_doc;//new $.ajatus.document.loader(_self.ready_doc._id, _self.ready_doc._rev, false, false);
112             doc.value = $.extend(doc.value, new_parts);
113             
114             var db_path = $.ajatus.preferences.client.content_database;
115             
116             $.jqCouch.connection('doc').save(db_path, doc);
117             _self.ready_doc = doc;//new $.ajatus.document(doc);
118         },
119         add_metadata: function() {
120             var self = this;
121             this.ready_doc.value.metadata = {};
122             $.each($.ajatus.document.metadata, function(k,m){
123                 self.ready_doc.value.metadata[k] = {
124                     val: '',
125                     widget: m.widget
126                 };
127             });
128         },
129         check_metadata: function() {
130             // console.log("check metadata");
131             var self = this;
132             var changed = false;
133             var new_md_parts = {};
134             $.each($.ajatus.document.metadata, function(k,m){
135                 // console.log("self.ready_doc.value.metadata["+k+"]:"+self.ready_doc.value.metadata[k])
136                 if (typeof(self.ready_doc.value.metadata[k]) == 'undefined') {
137                     def_val = '';
138                     if (typeof m['def_val'] != 'undefined') {
139                         def_val = m['def_val'];
140                     }
141                     new_md_parts[k] = {
142                         val: def_val,
143                         widget: m.widget
144                     };
145                     changed = true;
146                 } else {
147                     def_val = self.ready_doc.value.metadata[k].val || '';
148                     if (typeof m['def_val'] != 'undefined') {
149                         def_val = m['def_val'];
150                     }                    
151                     self.ready_doc.value.metadata[k] = $.extend({
152                         val: def_val,
153                         widget: m.widget                        
154                     }, self.ready_doc.value.metadata[k]);
155                 }
156             });
157             
158             if (changed) {
159                 self._fix_metadata(new_md_parts);
160             }
161         },
162         _fix_metadata: function(new_metadata) {
163             var _self = this;
164             
165             // console.log("_fix_metadata for: "+_self.ready_doc._id);
166             // console.log(new_metadata);
167             
168             doc = new $.ajatus.document.loader(_self.ready_doc._id, _self.ready_doc._rev, false);
170             // console.log("Before:");
171             // console.log(doc.value.metadata);
172             
173             doc.value.metadata = $.extend({}, doc.value.metadata, new_metadata);
174             
175             // console.log("After:");
176             // console.log(doc.value.metadata);
177             
178             var db_path = $.ajatus.preferences.client.content_database;
179             
180             $.jqCouch.connection('doc').save(db_path, doc);
181             _self.ready_doc = new $.ajatus.document(doc);
182         },
183         prepare_doc_title: function() {
184             var self = this;
186             if (   $.ajatus.preferences.client.content_types[this.ready_doc.value._type]['title_item']
187                 && (   typeof(this.ready_doc.value['title']) == 'undefined'
188                     || this.ready_doc.value['title'].val != '') ) {
189                 $.ajatus.preferences.client.content_types[this.ready_doc.value._type].schema['title'] = {
190                     label: 'Title',
191                     widget: {
192                         name: 'text',
193                         config: {}
194                     },
195                     hidden: true
196                 };
198                 var title_val = '';
199                 $.each($.ajatus.preferences.client.content_types[this.ready_doc.value._type]['title_item'], function(i,part){
200                     if (self.ready_doc.value[part]) {
201                         var widget = new $.ajatus.widget(self.ready_doc.value[part].widget.name, self.ready_doc.value[part].widget.config);
202                         var val = widget.value_on_view(self.ready_doc.value[part].val, 'plain');
203                         if (typeof val != 'string') {
204                             val = self.ready_doc.value[part].val;
205                         }
206                         title_val += val;
207                     } else {
208                         title_val += $.ajatus.i10n.get(part);
209                     }
210                 });
212                 this.ready_doc.value['title'] = {
213                     val: title_val,
214                     widget: $.ajatus.preferences.client.content_types[this.ready_doc.value._type].schema['title'].widget
215                 };
216             }
217         }
218     });
219     $.ajatus.document.loader = function(id, rev, check_metadata) {
220         if (typeof check_metadata == 'undefined') {
221             var check_metadata = true;            
222         }
223         
224         var args = {};
225         if (   typeof rev != 'undefined'
226             && rev != '')
227         {
228             args['rev'] = rev;
229         }
230         
231         return new $.ajatus.document(
232             $.jqCouch.connection('doc').get($.ajatus.preferences.client.content_database + '/' + id, args),
233             check_metadata,
234             true
235         );
236     };
237     $.ajatus.document.revisions = {
238         get: function(doc) {
239             // console.log("get_revisions for "+doc._id);
240             if (typeof doc._revs_info == 'undefined') {
241                 doc = $.jqCouch.connection('doc').get($.ajatus.preferences.client.content_database + '/' + doc._id, {
242                     _rev: doc._rev,
243                     revs_info: true
244                 });
245             }
247             var available_revs = [];
248             var active_rev_status = false;
249             $.each(doc._revs_info, function(i,n){
250                 if (n.rev == doc._rev) {
251                     active_rev_status = n.status;
252                 } else {
253                     if (n.status == 'disk') {
254                         available_revs.push(n);
255                     }
256                 }
257             });
259             var revs_data = {};
260             revs_data['active'] = {
261                 rev: doc._rev,
262                 status: active_rev_status
263             };
264             revs_data['available'] = available_revs;
265             revs_data['all'] = doc._revs_info;
267             // console.log("Revs data:");
268             // console.log(revs_data);
270             return revs_data;            
271         },
272         navigate_to: function(pos, current, rev_data) {
273             // console.log("Navigate_to ("+pos+"), current rev: "+current);
274             
275             var behind = [];
276             var ahead = [];
277             var revisions = rev_data.all;
278             
279             var put_behind = true;
280             var rev_idxs = {};
281             $.each(revisions, function(i,n){
282                 rev_idxs[n.rev] = i;
283                 if (n.rev == current) {
284                     put_behind = false;
285                     return;
286                 }
287                 if (put_behind) {
288                     behind.push(n.rev);
289                 } else {
290                     ahead.push(n.rev);
291                 }
292             });
293             
294             var curr_key = rev_idxs[current];
295             
296             // console.log("Behind:");
297             // console.log(behind);
298             // console.log("Ahead:");
299             // console.log(ahead);
300             
301             var return_rev = null;
302             
303             switch(pos) {
304                 case 'first':
305                     if (typeof ahead[(ahead.length-1)] != 'undefined') {
306                         return_rev = ahead[(ahead.length-1)];
307                         curr_key = rev_idxs[return_rev];
308                     }
309                 break;
310                 case 'last':
311                     if (typeof behind[0] != 'undefined') {
312                         return_rev = behind[0];
313                         curr_key = rev_idxs[return_rev];
314                     }
315                     if (rev_data.active.rev == current) {
316                         curr_key = rev_idxs[current];
317                         return_rev = null;
318                     }
319                 break;
320                 case 'next':
321                     if (typeof behind[(behind.length-1)] != 'undefined') {
322                         return_rev = behind[(behind.length-1)];
323                         curr_key = rev_idxs[return_rev];                        
324                     } else if (typeof ahead[0] != 'undefined') {
325                         return_rev = ahead[0];
326                         curr_key = rev_idxs[return_rev];
327                     }
328                     
329                     if (rev_data.active.rev == current) {
330                         curr_key = rev_idxs[current];
331                         return_rev = null;
332                     }
333                 break;
334                 case 'prev':
335                     if (typeof ahead[0] != 'undefined') {
336                         return_rev = ahead[0];
337                         curr_key = rev_idxs[return_rev];
338                     }
339                 break
340             }
342             // console.log("Total revs: "+revisions.length);
343             // console.log("curr_key: "+curr_key);
344             // console.log("Current: "+(revisions.length - (curr_key)));
345             // 
346             // console.log("Return rev: "+return_rev);
347             
348             return {
349                 total: revisions.length,
350                 current: (revisions.length - curr_key),
351                 rev: return_rev
352             };
353         }
354     };
355     $.ajatus.document.metadata = {
356         creator: {
357             label: 'Creator',
358             widget: {
359                 name: 'text',
360                 config: {}
361             }
362         },
363         created: {
364             label: 'Created',
365             widget: {
366                 name: 'date',
367                 config: {
368                     use_time: true
369                 }
370             }
371         },
372         revisor: {
373             label: 'Revisor',
374             widget: {
375                 name: 'text',
376                 config: {}
377             }
378         },
379         revised: {
380             label: 'Revised',
381             widget: {
382                 name: 'date',
383                 config: {
384                     use_time: true
385                 }
386             }
387         },
388         archived: {
389             label: 'Archived',
390             widget: {
391                 name: 'boolean',
392                 config: {}
393             },
394             def_val: false
395         },
396         deleted: {
397             label: 'Deleted',
398             widget: {
399                 name: 'boolean',
400                 config: {}
401             },
402             def_val: false
403         }
404     };
405     $.ajatus.document.modify_metadata = function(doc, metadata) {
406         $.each(metadata, function(k,v){
407             if ($.ajatus.document.metadata[k])
408             {
409                 var wdgt = new $.ajatus.widget($.ajatus.document.metadata[k].widget.name, $.ajatus.document.metadata[k].widget.config);
410                 doc.value.metadata[k] = {
411                     val: wdgt.value_on_save(wdgt.value_on_save(v)),
412                     widget: $.ajatus.document.metadata[k].widget
413                 };
414             }
415         });
416         
417         return doc;
418     };
419     $.ajatus.document.actions = {        
420         execute: function(action, tmpdoc) {
421             if (   typeof tmpdoc._rev != 'undefined'
422                 && tmpdoc._rev != null)
423             {
424                 var doc = new $.ajatus.document.loader(tmpdoc._id, tmpdoc._rev);                
425             } else {
426                 var doc = new $.ajatus.document.loader(tmpdoc._id);
427             }
428             
429             var act_info = $.ajatus.document.actions._get_action_info(action);
430             if (! act_info) {
431                 var msg = $.ajatus.elements.messages.create(
432                     $.ajatus.i10n.get('Unknown document action'),
433                     $.ajatus.i10n.get('Unknown action %s requested for object %s!', [action, doc.value.title.val])
434                 );
435                 return false;
436             }
437             
438             if (act_info.pool_action)
439             {
440                 var pa = act_info.pool_action;
441                 var pai = $.ajatus.document.actions._get_action_info(fa);
442                 if (pai) {
443                     var pool_action = {
444                         action: fa,
445                         doc: doc
446                     };
447                     var pool_id = $.ajatus.document.history.pool.add(pool_action);
448                 }
449             }
450             
451             if (act_info.undoable) {                
452                 $.ajatus.document.actions._execute_temp(act_info.action, doc);
453             } else {
454                 $.ajatus.document.actions._execute_final(act_info.action, doc);
455             }
456         },
457         _execute_temp: function(action, doc) {
458             // console.log("_execute_temp: "+action);
459             switch(action) {
460                 case 'delete':
461                     var on_success = function(data) {
462                         var tmpdoc = {
463                             _id: doc._id,
464                             _rev: doc._rev
465                         };
466                         var msg = $.ajatus.elements.messages.create(
467                             $.ajatus.i10n.get('Object deleted'),
468                             $.ajatus.i10n.get('Object %s moved to trash.', [doc.value.title.val]) + ' <a href="#undelete.'+doc.value._type+'.'+doc._id+'" class="undo">' + $.ajatus.i10n.get('Undo') + '</a>'
469                         );
470                         msg.bind_in_content('click', 'a.undo', function(e){
471                             $.ajatus.document.actions.execute("undelete", tmpdoc);
472                             msg.fade('out', true);
473                         });
474                         
475                         return data;
476                     };
478                     doc = $.ajatus.document.modify_metadata(doc, {
479                         deleted: true,
480                         revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
481                         revisor: $.ajatus.preferences.local.user.email
482                     });
483                     
484                     $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.content_database, doc);
485                     
486                     $('#object_'+doc._id, $.ajatus.application_content_area).hide().addClass('deleted');
487                 break;
488                 case 'archive':
489                     var on_success = function(data) {
490                         var tmpdoc = {
491                             _id: doc._id,
492                             _rev: doc._rev
493                         };
494                         var msg = $.ajatus.elements.messages.create(
495                             $.ajatus.i10n.get('Object archived'),
496                             $.ajatus.i10n.get('Object %s moved to archive.', [doc.value.title.val]) + ' <a href="#unarchive.'+doc.value._type+'.'+doc._id+'" class="undo">' + $.ajatus.i10n.get('Undo') + '</a>'
497                         );
498                         msg.bind_in_content('click', 'a.undo', function(e){
499                             $.ajatus.document.actions.execute("unarchive", tmpdoc);
500                             msg.fade('out', true);
501                         });
502                         
503                         return data;
504                     };
506                     doc = $.ajatus.document.modify_metadata(doc, {
507                         revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
508                         revisor: $.ajatus.preferences.local.user.email,
509                         archived: true
510                     });
511                     
512                     $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.content_database, doc);
513                     
514                     $('#object_'+doc._id, $.ajatus.application_content_area).hide().addClass('archived');
515                 break;
516             };
517         },
518         _execute_final: function(action, doc) {
519             switch(action) {
520                 case 'delete':
521                     var on_success = function(data) {
522                         var msg = $.ajatus.elements.messages.create(
523                             $.ajatus.i10n.get('Object deleted'),
524                             $.ajatus.i10n.get('Object %s removed from Ajatus.', [doc.value.title.val])
525                         );
526                         
527                         return data;
528                     };
529                     $.jqCouch.connection('doc', on_success).del($.ajatus.preferences.client.content_database, doc);
530                     $('#object_'+doc._id, $.ajatus.application_content_area).remove();
531                 break;
532                 case 'undelete':
533                     var on_success = function(data) {
534                         var msg = $.ajatus.elements.messages.create(
535                             $.ajatus.i10n.get('Object restored'),
536                             $.ajatus.i10n.get('Object %s restored succesfully.', [doc.value.title.val])
537                         );
538                         
539                         return data;
540                     };
541                     doc = $.ajatus.document.modify_metadata(doc, {
542                         deleted: false,
543                         revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
544                         revisor: $.ajatus.preferences.local.user.email
545                     });
546                     $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.content_database, doc);
547                     
548                     $('#object_'+doc._id, $.ajatus.application_content_area).not('.deleted').remove();
549                     $('#object_'+doc._id, $.ajatus.application_content_area).filter('.deleted').show().removeClass('deleted');
550                 break;
551                 case 'unarchive':
552                     var on_success = function(data) {
553                         var msg = $.ajatus.elements.messages.create(
554                             $.ajatus.i10n.get('Object restored'),
555                             $.ajatus.i10n.get('Object %s restored succesfully.', [doc.value.title.val])
556                         );
557                         
558                         return data;
559                     };
560                     doc = $.ajatus.document.modify_metadata(doc, {
561                         revised: $.ajatus.formatter.date.js_to_iso8601(new Date()),
562                         revisor: $.ajatus.preferences.local.user.email,
563                         archived: false
564                     });
565                     $.jqCouch.connection('doc', on_success).save($.ajatus.preferences.client.content_database, doc);
566                     
567                     $('#object_'+doc._id, $.ajatus.application_content_area).filter('.archived').show().removeClass('archived');
568                 break;
569             };
570         },
571         empty_pool: function () {
572             var items = $.ajatus.document.history.pool.get_all();
573             if (items.length > 0) {
574                 var msg = $.ajatus.elements.messages.create(
575                     $.ajatus.i10n.get('Emptying action pool'),
576                     $.ajatus.i10n.get('Running %d pooled actions.', [items.length])
577                 );                
578             }
579             $.each(items, function(i,item){
580                 $.ajatus.document.history.pool.remove(i);
581                 $.ajatus.document.actions.execute(item.action, item.doc);
582             });
583         },
584         _get_action_info: function(action) {
585             switch(action) {
586                 case 'delete':
587                     return {
588                         action: 'delete',
589                         label: $.ajatus.i10n.get('Delete'),
590                         undoable: true,
591                         undo_label: $.ajatus.i10n.get('Undelete'),
592                         pool_action: false
593                     }
594                 break;
595                 case 'delete_final':
596                     return {
597                         action: 'delete',
598                         label: $.ajatus.i10n.get('Delete'),
599                         undoable: false,
600                         pool_action: false
601                     }
602                 break;
603                 case 'undelete':
604                     return {
605                         action: 'undelete',
606                         label: $.ajatus.i10n.get('Undelete'),
607                         undoable: false,
608                         pool_action: false
609                     }
610                 break;
611                 case 'archive':
612                     return {
613                         action: 'archive',
614                         label: $.ajatus.i10n.get('Archive'),
615                         undoable: true,
616                         undo_label: $.ajatus.i10n.get('Restore'),
617                         pool_action: false
618                     }
619                 break;
620                 case 'unarchive':
621                     return {
622                         action: 'unarchive',
623                         label: $.ajatus.i10n.get('Restore'),
624                         undoable: false,
625                         pool_action: false
626                     }
627                 break;
628                 default:
629                     return false;
630             }
631         }
632     };
633     
634     $.ajatus.document.history = {};
635     $.ajatus.document.history.pool = {
636         items: [],
637         
638         add: function(action) {
639             var new_length = $.ajatus.document.history.pool.items.push(action);
640             var pool_id = new_length-1;
641             return pool_id;
642         },        
643         remove: function(item_id) {
644             $.ajatus.document.history.pool.items = $.grep($.ajatus.document.history.pool.items, function(n,i){
645                 return i != item_id;
646             });
647         },        
648         get_item: function(item_id) {
649             if (items[item_id]) {
650                 return items[item_id];
651             } else {
652                 return false;
653             }
654         },        
655         get_all: function() {
656             return $.ajatus.document.history.pool.items;
657         }
658     };
659     
660     $.ajatus.document.additionals = {
661         defaults: {
662             auto_show: true
663         },
664         open: [],
665         active: null,
666         top_start: 22,
667         left_start: 20
668     };
669     $.extend($.ajatus.document.additionals, {
670         create: function(content_type, row_holder, opts) {
671             $.ajatus.document.additionals._reset();
672             
673             var id = $.ajatus.document.additionals._generate_id();
674             
675             var options = $.ajatus.document.additionals.defaults;
676             options = $.extend(
677                 options,
678                 opts || {}
679             );
681             var af_win = $.ajatus.document.additionals._create_structure(id, options);
682             $('.title', af_win).html($.ajatus.i10n.get('Add field'));
683             
684             var jqform = $('.form', af_win);
685             var contents = $('.contents', af_win);
686             
687             var wdgts = $.ajatus.document.additionals._generate_widget_list();
688                         
689             $('<label for="widget"/>').html($.ajatus.i10n.get('Widget')).appendTo(contents);
690             var wdgt_sel_holder = $('<div id="widget_selection_holder"/>');
691             wdgt_sel_holder.html(wdgts).appendTo(contents);
692             
693             var wdgt_details = $('<div id="widget_details_holder"/>');
694             wdgt_details.appendTo(contents);
695             
696             var wdgts_on_change = function(e){
697                 var sel_w = e.currentTarget.value;
698                 if (sel_w != '') {
699                     wdgt_sel_holder.html($.ajatus.i10n.get(sel_w));
700                     wdgt_sel_holder.addClass('selected');
701                     wdgt_details.html($.ajatus.document.additionals._generate_widget_details(sel_w));
703                     var field = $('<input type="hidden" />').attr({
704                         name: '_widget',
705                         value: sel_w
706                     });
707                     field.appendTo(jqform);
708                 }
709             };
710             
711             wdgts.bind('change', wdgts_on_change);
712             
713             wdgt_sel_holder.bind('dblclick', function(e){
714                 wdgt_sel_holder.removeClass('selected');
715                 wdgt_sel_holder.html(wdgts);
716                 wdgts.bind('change', wdgts_on_change);
717             });
718             
719             $('.actions #submit_save', af_win).bind('click', function(e){
720                 var result = $.ajatus.document.additionals.save_widget(jqform.formToArray(false), jqform);
721                 
722                 if (result) {
723                     $.ajatus.document.additionals.close(id);
724                 }
725                 
726                 return false;
727             });
728             
729             if (options.auto_show) {
730                 $.ajatus.document.additionals.show(id);
731             }
732         },
733         edit: function(content_type, row_holder, data, opts) {
734             $.ajatus.document.additionals._reset();
735             
736             var id = $.ajatus.document.additionals._generate_id();
737             console.log("Edit win id: "+id);
738             
739             var options = $.ajatus.document.additionals.defaults;
740             options = $.extend(
741                 options,
742                 opts || {}
743             );
745             var af_win = $.ajatus.document.additionals._create_structure(id, options);
746             $('.title', af_win).html($.ajatus.i10n.get('Edit field %s', [data.name]));
747             
748             $('.actions #submit_save', af_win).bind('click', function(e){
749                 console.log("save additional field (on edit)");
750                 $.ajatus.document.additionals.close(id);
751             });
752             
753             if (options.auto_show) {
754                 $.ajatus.document.additionals.show(id);
755             }
756         },
757         config: function(widget, prev_vals, on_save) {
758             if (typeof prev_vals == 'undefined') {
759                 var prev_vals = {};
760             }
761             if (typeof on_save == 'undefined') {
762                 var on_save = '$.ajatus.document.additionals.save_widget_settings';
763             }
764             
765             var id = $.ajatus.document.additionals._generate_id();
766             
767             var af_win = $.ajatus.document.additionals._create_structure(id);
768             $('.title', af_win).html($.ajatus.i10n.get('Configure widget %s', [$.ajatus.i10n.get(widget.name)]));
769             
770             var jqform = $('.form', af_win);
771             var contents = $('.contents', af_win);
772             
773             var wdgt_settings = $('<div id="widget_settings_holder" />');
774             wdgt_settings.appendTo(contents);
775             wdgt_settings.html($.ajatus.document.additionals._generate_widget_settings(widget, prev_vals));
776             
777             $('.actions #submit_save', af_win).bind('click', function(e){                
778                 var parent_win = $.ajatus.document.additionals._get_parent();
780                 var fn = on_save;
781                     if (typeof on_save == 'string') {
782                     fn = eval(on_save);
783                 }
784                 var result = fn.apply(fn, [jqform.formToArray(false), parent_win, jqform]);
785                 
786                 if (result) {
787                     $.ajatus.document.additionals.close(id);
788                 }
789             });
790             
791             $.ajatus.document.additionals.show(id);
792         },
793         show: function(id) {
794             $.ajatus.document.additionals.active = id;
795             $.ajatus.document.additionals.open.push(id);
796             $.ajatus.document.additionals._position(id);
797                         
798             $('#'+id).show();
799         },
800         close: function(id) {            
801             if (typeof id == 'undefined') {
802                 var id = $.ajatus.document.additionals.active;
803             }
804             
805             $('#'+id).hide();
806             
807             var active_idx = null;
808             var still_open = $.grep($.ajatus.document.additionals.open, function(n,i){
809                 if (n != id) {
810                     return true;
811                 } else {
812                     active_idx = i;
813                     return false;
814                 }
815             });
816             
817             if (   active_idx > 0
818                 && $.ajatus.document.additionals.open.length-1 >= (active_idx-1))
819             {
820                 $.ajatus.document.additionals.active = still_open[active_idx-1];
821             } else {
822                 $.ajatus.document.additionals.active = null;
823             }
824             
825             $.ajatus.document.additionals.open = still_open;
826         },
827         save_widget_settings: function(form_data, parent_win_id, form) {
828             var form_values = {};
829             
830             $.each(form_data, function(i,row){
831                 if (row.name.toString().match(/__(.*?)/)) {
832                     return;
833                 }
834                     if (row.name.substr(0,6) != "widget") {
835                         var item = {};
836                         var widget = {};
837                         var prev_val = false;
838                         var name_parts = [];
839                         var name_parts_count = 0;
840                         if (row.name.toString().match(/;/g)) {
841                             name_parts = row.name.toString().split(";");
842                             name_parts_count = name_parts.length;
843                         }
844                         
845                         $.each(form_data, function(x,r){
846                             if (r.name == 'widget['+row.name+':name]') {
847                                 widget['name'] = r.value;
848                             } else if (r.name == 'widget['+row.name+':config]') {
849                             widget['config'] = $.ajatus.converter.parseJSON(r.value);
850                         } else if (r.name == 'widget['+row.name+':prev_val]') {
851                             prev_val = $.ajatus.converter.parseJSON(r.value);
852                         }
853                     });
855                     var wdgt = new $.ajatus.widget(widget['name'], widget['config']);
857                         item['val'] = wdgt.value_on_save(row.value, prev_val);
858                         item['widget'] = widget;
859                         
860                         if (name_parts_count > 0) {
861                             var prevs = [];
862                             for (var i=0; i < name_parts_count; i++) {
863                                 var key = "['"+name_parts[i]+"']";
864                             
865                             if (prevs.length > 0) {
866                                 var key_prefix = '';
867                                 $.each(prevs, function(pi, pk){
868                                     key_prefix = "['" + pk + "']" + key_prefix;
869                                 });
870                                 key = key_prefix + key;
871                             }
872                             
873                                 if (typeof eval("form_values"+key) == 'undefined') {
874                                     eval("form_values"+key+"={};");
875                                 }
876                                 
877                                 prevs.push(name_parts[i]);
878                             if (i == name_parts_count-1) {
879                                 if ($.browser.mozilla) {
880                                     if (typeof item == 'object') {
881                                         eval("form_values"+key+"="+item.toSource()+";");
882                                     } else {
883                                         eval("form_values"+key+"="+item+";");
884                                     }
885                                 } else {
886                                     eval("form_values"+key+"="+item+";");
887                                 }
888                             }
889                             }
890                         } else {
891                             form_values[row.name] = item;
892                         }
893                     }
894             });
895             
896             var config_holder = $('#'+parent_win_id+' .saved_settings');
897             config_holder.html('');
898             
899             $.each(form_values, function(k,item){
900                 var field = $('<input type="hidden" />').attr({
901                     name: 'config;'+k,
902                     value: $.ajatus.converter.toJSON(item.val)
903                 });
904                 field.appendTo(config_holder);
905             });
906             
907             return true;
908         },
909         save_widget: function(form_data, form) {
910             var form_values = {};
911             var sel_widget = 'text';
912             
913             // console.log(form_values);
914             
915             $.each(form_data, function(i,row){                  
916                 if (row.name.toString().match(/__(.*?)/)) {
917                     return;
918                 }
919                 if (row.name == '_widget') {
920                     sel_widget = String(row.value);
921                 }
922                     else if (row.name.substr(0,6) != "widget") {                        
923                         var item = {};
924                         var widget = {};
925                         var prev_val = false;
926                         var name_parts = [];
927                         var name_parts_count = 0;
928                         
929                         if (row.name.toString().match(/;/g)) {
930                             name_parts = row.name.toString().split(";");
931                             name_parts_count = name_parts.length;
932                         }
933                         
934                         $.each(form_data, function(x,r){
935                             if (r.name == 'widget['+row.name+':name]') {
936                                 widget['name'] = r.value;
937                             } else if (r.name == 'widget['+row.name+':config]') {
938                             widget['config'] = $.ajatus.converter.parseJSON(r.value);
939                         } else if (r.name == 'widget['+row.name+':prev_val]') {
940                             prev_val = $.ajatus.converter.parseJSON(r.value);
941                         }
942                     });
943                     
944                     if (typeof widget['name'] == 'undefined') {
945                         return;
946                     }
948                     var wdgt = new $.ajatus.widget(widget['name'], widget['config']);
950                         item['val'] = wdgt.value_on_save(row.value, prev_val);
951                         item['widget'] = widget;
952                         
953                         if (name_parts_count > 0) {
954                         // console.log("name_parts_count > 0");
955                             var prevs = [];
956                             for (var i=0; i < name_parts_count; i++) {
957                                 var key = "['"+name_parts[i]+"']";
958                             
959                             if (prevs.length > 0) {
960                                 var key_prefix = '';
961                                 $.each(prevs, function(pi, pk){
962                                     key_prefix = "['" + pk + "']" + key_prefix;
963                                 });
964                                 key = key_prefix + key;
965                             }
966                             
967                                 if (typeof eval("form_values"+key) == 'undefined') {
968                                     eval("form_values"+key+"={};");
969                                 }
970                                 
971                                 prevs.push(name_parts[i]);
972                             if (i == name_parts_count-1) {
973                                 if ($.browser.mozilla) {
974                                     if (typeof item == 'object') {
975                                         eval("form_values"+key+"="+item.toSource()+";");
976                                     } else {
977                                         eval("form_values"+key+"="+item+";");
978                                     }
979                                 } else {
980                                     eval("form_values"+key+"="+item+";");
981                                 }
982                             }
983                             }
984                         } else {
985                             form_values[row.name] = item;
986                         }
987                     }
988             });
989             
990             // var additional_items = {};
991             
992             var config = {};
993             if (typeof form_values['config'] != 'undefined') {
994                 $.each(form_values['config'], function(i,n){
995                     if (typeof n == 'object') {
996                         config[i] = $.ajatus.converter.parseJSON(n.val);
997                     } else {
998                         config[i] = n;
999                     }
1000                 });                
1001             }
1002             
1003             var item_name = form_values.name.val.toString().toLowerCase();
1004             
1005             if (item_name == '') {
1006                 return false;
1007             }
1008             
1009             var additional_item = {
1010                 label: form_values.label.val,
1011                 widget: {
1012                     name: sel_widget,
1013                     config: config
1014                 },
1015                 def_val: form_values.def_val.val,
1016                 required: form_values.required.val
1017             };
1018             // additional_items[item_name] = additional_item;
1019             // console.log(additional_items);
1020             // console.log(additional_item);
1021             
1022             var row_holder = $('.form_structure ul.row_holder:eq(0)', $.ajatus.forms.active);
1024             $.ajatus.renderer.form_helpers._add_additional_row('create', row_holder, item_name, additional_item);
1025             
1026             return true;
1027         },
1028         generate_item_actions_tpl: function(name, widget, doc) {
1029             return [
1030                 'img', { className: 'additional_edit_btn', src: $.ajatus.preferences.client.theme_icons_url + 'edit.png', title: $.ajatus.i10n.get('Edit'), alt: $.ajatus.i10n.get('Edit') }, '',
1031                 'img', { className: 'additional_delete_btn', src: $.ajatus.preferences.client.theme_icons_url + 'trash.png', title: $.ajatus.i10n.get('Delete'), alt: $.ajatus.i10n.get('Delete') }, '',
1032             ];
1033         },
1034         _get_parent: function() {            
1035             var prev_id = $.ajatus.document.additionals.open[$.ajatus.document.additionals.open.length-2];
1036             
1037             return prev_id;
1038         },
1039         _position: function(id) {
1040             var win = $('#' + id);
1041             var top = $.ajatus.document.additionals.top_start;
1042             var left = $.ajatus.document.additionals.left_start;
1043             
1044             if ($.ajatus.document.additionals.open.length > 1) {
1045                 var incr = $.ajatus.document.additionals.open.length * 2;
1046                 top += incr;
1047                 left += incr;
1048             }
1050             win.css({
1051                 top: top+'%',
1052                 left: left+'%'
1053             });
1054         },
1055         _create_structure: function(id, options) {            
1056             var af_win = $('<div class="additionals_window" />').attr({
1057                 id: id
1058             }).hide();
1059             var title = $('<h2 class="title"/>');
1060             var form = $('<form id="additionals_window_form" class="form" />');
1061             var content_area = $('<div class="contents"/>');
1062             var actions = $('<div class="actions" />').html('<input type="submit" id="submit_save" name="save" value="' + $.ajatus.i10n.get('Save') + '" /><input type="submit" id="submit_cancel" name="cancel" value="' + $.ajatus.i10n.get('Cancel') + '" />');
1063                                     
1064             af_win.appendTo($.ajatus.application_dynamic_elements);
1065             title.appendTo(af_win);
1066             form.appendTo(af_win);
1067             content_area.appendTo(form);
1068             actions.appendTo(af_win);
1070             $('#submit_cancel', actions).bind('click', function(e){
1071                 $.ajatus.document.additionals.close(id);
1072                 return false;
1073             });
1074             
1075             return af_win;
1076         },
1077         _generate_widget_list: function() {
1078             var select = $('<select id="widget" name="widget" />');
1079                         
1080             $.each($.ajatus.widgets.loaded_widgets, function(i,w){
1081                 var opt = $('<option />').attr({
1082                     value: w
1083                 }).html($.ajatus.i10n.get(w));
1084                 opt.appendTo(select);
1085             });
1087             var opt = $('<option />').attr({
1088                 value: '',
1089                 selected: 'selected'
1090             }).html($.ajatus.i10n.get('Select one') + '&nbsp;');
1091             opt.prependTo(select);
1092             
1093             return select;
1094         },
1095         _generate_widget_details: function(widget_name, data) {
1096             var widget = $.ajatus.widget(widget_name);
1097             var details = $('<p>' + $.ajatus.i10n.get("Widget %s doesn't support dynamic creation.", [$.ajatus.i10n.get(widget_name)]) + '</p>');
1098             if (typeof(widget['create_widget_details']) == 'function') {
1099                 details = widget.create_widget_details(data || {});
1100             }
1101             
1102             return details;
1103         },
1104         _generate_widget_settings: function(widget_name, data) {
1105             var widget = $.ajatus.widget(widget_name);
1106             var details = $('<p>' + $.ajatus.i10n.get("Widget %s doesn't support dynamic settings.", [$.ajatus.i10n.get(widget_name)]) + '</p>');
1107             if (typeof(widget['create_widget_settings']) == 'function') {
1108                 details = widget.create_widget_settings(data || {});
1109             }
1110             
1111             return details;
1112         },
1113         _reset: function() {
1114             $.ajatus.document.additionals.open = [];
1115             $.ajatus.document.additionals.active = null;
1116             $.ajatus.application_dynamic_elements.html('');
1117         },
1118         _generate_id: function()
1119         {
1120             return "additionals_window_" + $.ajatus.utils.generate_id();
1121         }
1122     });
1124 })(jQuery);