1 var Class = require("../lib/mootools/mootools-node.js").Class;
  2 var JsonRpcError = require("../lib/core/jsonrpc/JsonRpcError.js").JsonRpcError;
  3 
  4 var EventDispatcher = require('../lib/core/event/EventDispatcher.js').EventDispatcher;
  5 
  6 var Event = require('../lib/core/event/Event.js').Event;
  7 var Template = require('../lib/Template.js').Template;
  8 /**
  9  * @class Responsible for managing templates. 
 10  * @extends EventDispatcher
 11  * @requires Class
 12  * @requires Event
 13  * @requires EventDispatcher
 14  * @requires JsonRpcError
 15  * @requires Template
 16  */
 17 var TemplateManager = function(){
 18     /** @ignore */
 19     this.Extends = EventDispatcher;
 20     
 21     /**
 22      * keeps references to attached templates
 23      * 
 24      * @private
 25      * 
 26      * @type {Template[]} 
 27      */
 28     this._templates = [];
 29     
 30     /**
 31      * helper property, keeps count of currently rendered elements
 32      * 
 33      * @private
 34      * 
 35      * @type {integer}
 36      */
 37     this._counter = 0;
 38     /**
 39      * 
 40      * @private
 41      * 
 42      * @type {boolean}
 43      */
 44     this._isAborted = false;
 45     /**
 46      * keeps the error which caused the abort
 47      * 
 48      * @private
 49      * 
 50      * @type {JsonRpcError}
 51      */
 52     this._abortError = undefined;
 53     
 54     /** @ignore */
 55     this.initialize = function(){
 56         this._templates = [];
 57         this._counter = 0;
 58     };
 59     
 60     /**
 61      * Indicates if rendering process was aborded.
 62      * @public
 63      * @returns {boolean}
 64      */
 65     this.isAborted = function(){
 66         return this._isAborted;
 67     };
 68 
 69     /**
 70      * Return templates content object.
 71      * @public
 72      * @returns {Object} 
 73      */
 74     this.getTemplatesContent = function(){
 75         //TODO wywalanie niepotrzebnych elementów
 76         var renderedTemplates = {};
 77         for( var i = 0; i < this._templates.length; i++){
 78             var template = this._templates[i];
 79 
 80             if(!template.hasParent){
 81                 if(this._isAborted){
 82                     var error = JsonRpcError.factory(TemplateManager.Error.ABORTING).setData(this._abortError).toJson();
 83                     renderedTemplates[template.getName()] = error;
 84                 }else{
 85                     renderedTemplates[template.getName()] = template.getContent();
 86                 }
 87             }
 88         }
 89         return renderedTemplates;
 90     };
 91     /**
 92      * Adds a template to collection
 93      * @public
 94      * @param {Template} template
 95      * @throws {TemplateManager.Exception.TEMPLATE_HAS_TO_INHERIT}
 96      * @returns {boolean}
 97      */
 98     this.addTemplate = function(template){
 99         if(!template || !(template instanceof Template)){
100             throw TemplateManager.Exception.TEMPLATE_HAS_TO_INHERIT;
101         }
102 
103         this._templates.push(template);
104         template.setTemplateManager(this);
105         template.addEventListener(Template.RENDERED, this._onTemplateRendered, this);
106 
107         return true;
108     };
109 
110     /**
111      * Removes template from collecion
112      * @public
113      * @param {Template} template
114      * @throws {TemplateManager.Exception.TEMPLATE_HAS_TO_INHERIT}
115      * @returns {boolean}
116      */
117     this.removeTemplate = function(template){
118         if(!template || !(template instanceof Template)){
119             throw TemplateManager.Exception.TEMPLATE_HAS_TO_INHERIT;
120         }
121 
122         for(var i = 0, l = this._templates.length; i < l; i++){
123             if(this._templates[i] == template){
124                 this._templates.splice(i, 1);
125                 return true;
126             }
127         }
128         
129         return false;
130     };
131     /**
132      * Returns template instance by given name
133      * @public
134      * @param {string} name templates name
135      * @throws {TemplateManager.Exception.NAME_MUST_BE_A_STRING}
136      * @returns {Template|null}
137      */
138     this.getTemplateByName = function(name){
139         if(typeof name != "string"){
140             throw TemplateManager.Exception.NAME_MUST_BE_A_STRING;
141         }
142         var result = null, i = 0, count = this._templates.length;
143 
144         while(i < count && name != this._templates[i].getName()){
145             i++;
146         }
147 
148         if(i < count){
149             result =  this._templates[i];   
150         }
151 
152         return result;
153     };
154     
155     /**
156      * Aborts rendering current tree. Dispatchig {@link TemplateManager.RENDERED}
157      * @public
158      */
159     this.abort = function(error){
160         //TODO zastanowic sie nad przeniesieniem logiki Abortowania flow renderingu z klasy TemplateManagera do klasy odpowiedzialnej za rendering - RenderingController. Jest to niepotrzebne mieszanie logiki renderowania i zarzadzania templateami.
161         for(var i = 0, l = this._templates.length; i < l; i++){
162             this._templates[i].removeEventListener(Template.RENDERED, this._onTemplateRendered);
163         }
164 
165         this._isAborted = true;
166         this._abortError = error;
167         this.dispatchEvent(new Event(TemplateManager.RENDERED));
168     };
169 
170     /**
171      * Event handler called on template rendered
172      *
173      * @param {Event} e
174      * @private
175      */
176     this._onTemplateRendered = function(e){
177         this._counter++;
178         if(this._counter == this._templates.length){
179             this.dispatchEvent(new Event(TemplateManager.RENDERED));
180         }
181     };
182 
183     /**
184      * Event handler called on template error
185      * 
186      * @param {ErrorEvent} e
187      * @private
188      */
189     this._onTemplateError = function(e){
190         //this._counter++;
191         //this.dispatchEvent(new ErrorEvent(TemplateManager.ERROR, e));
192     };
193 };
194 
195 
196 TemplateManager = new Class(new TemplateManager());
197 
198 /**
199  * Makes new template of specific type.
200  * Factory method
201  *
202  * @static
203  * @public
204  * @param {string} name Template's name/file path
205  * @param {object} configuration Configuration of transformation rule
206  * @returns {Template}
207  */
208 TemplateManager.createTemplate = function(name, configuration){
209     var template,
210         type = configuration.template.substring(configuration.template.lastIndexOf('.'), configuration.template.length);
211 
212     switch(type){
213         case TemplateManager.JQTEMPLATE:
214             console.log('   -- creating new JqTemplate: '+ name);
215             var JqTemplate = require('../lib/JqTemplate.js').JqTemplate;
216             template = new JqTemplate(name, configuration);
217         break;
218         default:
219             throw TemplateManager.Exception.UNRESOLVED_TYPE;
220         break;
221     }
222     
223     return template;
224 };
225 
226 /**
227  * @static
228  * @constant
229  */
230 TemplateManager.RENDERED = "TemplateManager_RENDERED";
231 /**
232  * @static
233  * @constant
234  */
235 TemplateManager.ERROR = "TemplateManager_ERROR";
236 /**
237  * @static
238  * @constant
239  */
240 TemplateManager.JQTEMPLATE = ".jqtpl";
241 /**
242  * Namespace for exeptions messages.
243  * @static
244  * @constant
245  * @namespace
246  */
247 TemplateManager.Exception = {};
248 /**
249  * @static
250  * @constant
251  */
252 TemplateManager.Exception.TEMPLATE_HAS_TO_INHERIT = 'Given template has to iherit from Template';
253 /**
254  * @static
255  * @constant
256  */
257 TemplateManager.Exception.NAME_MUST_BE_A_STRING = 'Template name has to be a string';
258 /**
259  * @static
260  * @constant
261  */
262 TemplateManager.Exception.UNRESOLVED_TYPE = "Error - unresolved template type.";
263 /**
264  * Namespace for error objects.
265  * @static
266  * @constant
267  * @namespace
268  */
269 TemplateManager.Error = {};
270 /**
271  * @static
272  * @constant
273  */
274 TemplateManager.Error.ABORTING = new JsonRpcError(-2101, "Aborted");
275 
276 exports.TemplateManager = TemplateManager;