/**
 * Copyright 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
 * Please see distribution for license.
 */

$.register_module({
    name: 'og.common.util.ui.Block',
    dependencies: ['og.api.text'],
    obj: function () {
        var module = this, STALL = 500 /* 500ms */, api_text = og.api.text;
        /** @private */
        var default_template = Handlebars.compile('{{{children}}}');
        /**
         * creates a Block instance
         * @name Block
         * @constructor
         * @param {Form} form parent Form instance
         * @param {Object} config configuation options for Block instance
         * @param {String} config.module the Handlebars template name (optional)
         * @param {String} config.content static content that will populate the Block (optional)
         * @param {Function} config.generator function that will receive a handler into which it can send Block contents
         * whenever it is ready, useful for populating a block with async content (optional)
         * @param {Object} config.extras values plugged into the Handlerbars template (optional)
         * @param {String} config.template simple Handlebars template, an HTML blob called "children" can be used to
         * wrap children
         * @property {Array} children collection of children within a Block instance, each child is itself a Block
         */
        var Block = function (form, config) {
            var block = this, config = block.config = config || {};
            block.children = config.children || [];
            block.form = form;
            if (config.template) {
                block.template = Handlebars.compile(config.template);
                return;
            }
            if (config.module) {
                api_text({module: config.module, loading: function () {block.template = 'loading';}})
                    .pipe(function (html) {block.template = Handlebars.compile(html);});
                return;
            }
            if (block.template) return; // if block inherited its template
            block.template = default_template;
        };
        /**
         * generates the HTML for a Block instance and all of its children and calls a supplied handler with that string
         * @param {Function} handler the handler that receives the HTML string
         * @param {Object} extras key/value pairs that will override the original config.extras that were passed in when
         * instantiated
         * @type Block
         * @returns {Block} reference to current Block instance
         */
        Block.prototype.html = function (handler, extras) {
            var block = this, template = block.template, total = block.children.length, done = 0, result = [],
                generator = block.config.generator;
            /** @private */
            var internal_handler = function () {
                var template_data = $.extend(
                    result.reduce(function (acc, val, idx) {return acc['item_' + idx] = val, acc;}, {
                        children: result.join('') // all children can be populated into a special field called children
                    }), block.config.extras, extras || {}
                );
                return generator ? generator(handler, template, template_data) : handler(template(template_data));
            };
            if (block.config.content) return handler(block.config.content), block;
            if (template === 'loading') return setTimeout(function () {block.html(handler);}, STALL), block;
            if (!total) return internal_handler(), block;
            block.children.forEach(function (val, idx) {
                val.html(function (html) {(result[idx] = html), (total === ++done) && internal_handler();});
            });
            return block;
        };
        /**
         * simulates a form:load event, only used when new blocks are added and need to be set up
         * @type Block
         * @returns {Block} reference to current Block instance
         */
        Block.prototype.load = function () {
            var block = this, form = block.form;
            if (form.events['form:load']) // mimic a form load event
                form.events['form:load'].forEach(function (val) {if (val.origin === block) val.handler();});
            block.children.forEach(function (child) {if (child.load) child.load();});
            return block;
        };
        /**
         * delegates off functionality to current Block instance's parent {@link Form#off}
         * @type Block
         * @returns {Block} reference to current Block instance
         */
        Block.prototype.off = function () {
            var block = this;
            return block.form ? block.form.off.apply(block, Array.prototype.slice.call(arguments)) : block;
        };
        /**
         * delegates on functionality to current Block instance's parent {@link Form#on}
         * @type Block
         * @returns {Block} reference to current Block instance
         */
        Block.prototype.on = function () {
            var block = this;
            return block.form ? block.form.on.apply(block, Array.prototype.slice.call(arguments)) : block;
        };
        /** @ignore */
        Block.prototype.process = function (data, errors) {
            var block = this, processor = block.config.processor;
            block.children.forEach(function (child) {if (child.process) child.process(data, errors);});
            try {if (processor) processor(data);} catch (error) {errors.push(error);}
        };
        Block.prototype.template = null;
        return Block;
    }
});
@@ -320,101 +320,8 @@
 xt;%0A
-        /** @private */%0A        var default_template = Handlebars.compile('%7B%7B%7Bchildren%7D%7D%7D');%0A
     
@@ -320,32 +320,32 @@
 xt;%0A        /**%0A
+
          * creat
@@ -1130,48 +1130,8 @@
 ren%22
- can be used to%0A         * wrap children
 %0A   
@@ -1455,151 +1455,8 @@
 rm;%0A
-            if (config.template) %7B%0A                block.template = Handlebars.compile(config.template);%0A                return;%0A            %7D%0A
     
@@ -1481,34 +1481,16 @@
 .module)
- %7B%0A               
  api_tex
@@ -1584,20 +1584,16 @@
         
-    
 .pipe(fu
@@ -1669,154 +1669,85 @@
     
- 
-   return;%0A            %7D%0A            if (block.template) return; // if block inherited its template%0A            block.template = default_
+else if (config.template) block.template = Handlebars.compile(config.
 template
 ;%0A  
@@ -1742,16 +1742,17 @@
 template
+)
 ;%0A      
@@ -2067,57 +2067,8 @@
 tras
- that were passed in when%0A         * instantiated
 %0A   
@@ -3233,23 +3233,27 @@
 nction (
-val, id
+child, inde
 x) %7B%0A   
@@ -3265,19 +3265,21 @@
         
-val
+child
 .html(fu
@@ -3302,17 +3302,19 @@
 result%5Bi
-d
+nde
 x%5D = htm
@@ -3953,24 +3953,8 @@
 d) %7B
-if (child.load) 
 chil
@@ -4995,27 +4995,8 @@
 d) %7B
-if (child.process) 
 chil
@@ -5159,12 +5159,44 @@
 e = 
-null
+Handlebars.compile('%7B%7B%7Bchildren%7D%7D%7D')
 ;%0A  

simplifying Block