/**
 * @license Handlebars hbs 0.4.0 - Alex Sexton, but Handlebars has it's own licensing junk
 *
 * Available via the MIT or new BSD license.
 * see: http://github.com/jrburke/require-cs for details on the plugin this was based off of
 */

/* Yes, deliciously evil. */
/*jslint evil: true, strict: false, plusplus: false, regexp: false */
/*global require: false, XMLHttpRequest: false, ActiveXObject: false,
define: false, process: false, window: false */
define([
    //>>excludeStart('excludeHbs', pragmas.excludeHbs)
    'handlebars', 'underscore', 'i18nprecompile'
    //>>excludeEnd('excludeHbs')
], function(
    //>>excludeStart('excludeHbs', pragmas.excludeHbs)
    Handlebars, _, precompile
    //>>excludeEnd('excludeHbs')
) {
    //>>excludeStart('excludeHbs', pragmas.excludeHbs)
    var fs, getXhr,
        progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
        fetchText = function() {
            throw new Error('Environment unsupported.');
        },
        buildMap = [],
        filecode = "w+",
        templateExtension = "hbs",
        customNameExtension = "@hbs",
        devStyleDirectory = "/styles/",
        buildStyleDirectory = "/demo-build/styles/",
        helperDirectory = "template/helpers/",
        i18nDirectory = "template/i18n/",
        buildCSSFileName = "screen.build.css";

    Handlebars.registerHelper('$', function() {
        //placeholder for translation helper
    });

    if (typeof window !== "undefined" && window.navigator && window.document && !window.navigator.userAgent.match(/Node.js/)) {
        // Browser action
        getXhr = function() {
            //Would love to dump the ActiveX crap in here. Need IE 6 to die first.
            var xhr, i, progId;
            if (typeof XMLHttpRequest !== "undefined") {
                return new XMLHttpRequest();
            } else {
                for (i = 0; i < 3; i++) {
                    progId = progIds[i];
                    try {
                        xhr = new ActiveXObject(progId);
                    } catch (e) {}

                    if (xhr) {
                        progIds = [progId]; // so faster next time
                        break;
                    }
                }
            }

            if (!xhr) {
                throw new Error("getXhr(): XMLHttpRequest not available");
            }

            return xhr;
        };

        fetchText = function(url, callback) {
            var prependComment = "<!--START: " + url + "--> == <!--END: " + url + "-->";
            var xhr = getXhr();
            xhr.open('GET', url, true);
            xhr.onreadystatechange = function(evt) {
                //Do not explicitly handle errors, those should be
                //visible via console output in the browser.
                if (xhr.readyState === 4) {
                    callback(xhr.responseText);
                    //TODO FIXME Gautam:Not working with backbone-forms when it does this : $($.trim(this.template(_.result(this, 'templateData'))));
                    // callback(prependComment.replace('==',xhr.responseText));
                }
            };
            xhr.send(null);
        };

    } else if (typeof process !== "undefined" &&
        process.versions &&
        !!process.versions.node) {
        //Using special require.nodeRequire, something added by r.js.
        fs = require.nodeRequire('fs');
        fetchText = function(path, callback) {
            var body = fs.readFileSync(path, 'utf8') || "";
            // we need to remove BOM stuff from the file content
            body = body.replace(/^\uFEFF/, '');
            callback(body);
        };
    } else if (typeof java !== "undefined" && typeof java.io !== "undefined") {
        fetchText = function(path, callback) {
            var f = new java.io.File(path);
            var is = new java.io.FileReader(f);
            var reader = new java.io.BufferedReader(is);
            var line;
            var text = "";
            while ((line = reader.readLine()) !== null) {
                text += new String(line) + "\n";
            }
            reader.close();
            callback(text);
        };
    }

    var cache = {};
    var fetchOrGetCached = function(path, callback) {
        if (cache[path]) {
            callback(cache[path]);
        } else {
            fetchText(path, function(data) {
                cache[path] = data;
                callback.call(this, data);
            });
        }
    };
    var styleList = [],
        styleMap = {};
    //>>excludeEnd('excludeHbs')

    return {

        get: function() {
            return Handlebars;
        },

        write: function(pluginName, name, write) {

            if ((name + customNameExtension) in buildMap) {
                var text = buildMap[name + customNameExtension];
                write.asModule(pluginName + "!" + name, text);
            }
        },

        version: '0.4.0',

        load: function(name, parentRequire, load, config) {
            //>>excludeStart('excludeHbs', pragmas.excludeHbs)

            var compiledName = name + customNameExtension,
                disableI18n = (config.hbs && config.hbs.disableI18n),
                partialDeps = [];

            function recursiveNodeSearch(statements, res) {
                _(statements).forEach(function(statement) {
                    if (statement && statement.type && statement.type === 'partial') {
                        res.push(statement.partialName.name);
                    }
                    if (statement && statement.program && statement.program.statements) {
                        recursiveNodeSearch(statement.program.statements, res);
                    }
                    if (statement && statement.program && statement.program.inverse && statement.program.inverse.statements) {
                        recursiveNodeSearch(statement.program.inverse.statements, res);
                    }
                });
                return res;
            }

            // TODO :: use the parser to do this!
            function findPartialDeps(nodes) {
                var res = [];
                if (nodes && nodes.statements) {
                    res = recursiveNodeSearch(nodes.statements, []);
                }
                return _(res).unique();
            }

            // See if the first item is a comment that's json
            function getMetaData(nodes) {
                var statement, res, test;
                if (nodes && nodes.statements) {
                    statement = nodes.statements[0];
                    if (statement && statement.type === "comment") {
                        try {
                            res = (statement.comment).replace(new RegExp('^[\\s]+|[\\s]+$', 'g'), '');
                            test = JSON.parse(res);
                            return res;
                        } catch (e) {
                            return "{}";
                        }
                    }
                }
                return "{}";
            }

            function composeParts(parts) {
                if (!parts) {
                    return [];
                }
                var res = [parts[0]],
                    cur = parts[0],
                    i;

                for (i = 1; i < parts.length; ++i) {
                    if (parts.hasOwnProperty(i)) {
                        cur += "." + parts[i];
                        res.push(cur);
                    }
                }
                return res;
            }

            function recursiveVarSearch(statements, res, prefix, helpersres) {
                prefix = prefix ? prefix + "." : "";

                var newprefix = "",
                    flag = false;

                // loop through each statement
                _(statements).forEach(function(statement) {
                    var parts, part, sideways;

                    // if it's a mustache block
                    if (statement && statement.type && statement.type === 'mustache') {

                        // If it has params, the first part is a helper or something
                        if (!statement.params || !statement.params.length) {
                            parts = composeParts(statement.id.parts);
                            for (part in parts) {
                                if (parts[part]) {
                                    newprefix = parts[part] || newprefix;
                                    res.push(prefix + parts[part]);
                                }
                            }
                            res.push(prefix + statement.id.string);
                        }

                        var paramsWithoutParts = ['this', '.', '..', './..', '../..', '../../..'];

                        // grab the params
                        if (statement.params && typeof Handlebars.helpers[statement.id.string] === 'undefined') {
                            _(statement.params).forEach(function(param) {
                                if (_(paramsWithoutParts).contains(param.original) || param instanceof Handlebars.AST.StringNode || param instanceof Handlebars.AST.IntegerNode || param instanceof Handlebars.AST.BooleanNode) {
                                    helpersres.push(statement.id.string);
                                }

                                parts = composeParts(param.parts);

                                for (var part in parts) {
                                    if (parts[part]) {
                                        newprefix = parts[part] || newprefix;
                                        helpersres.push(statement.id.string);
                                        res.push(prefix + parts[part]);
                                    }
                                }
                            });
                        }
                    }

                    // If it's a meta block
                    if (statement && statement.mustache) {
                        recursiveVarSearch([statement.mustache], res, prefix + newprefix, helpersres);
                    }

                    // if it's a whole new program
                    if (statement && statement.program && statement.program.statements) {
                        sideways = recursiveVarSearch([statement.mustache], [], "", helpersres)[0] || "";
                        if (statement.program.inverse && statement.program.inverse.statements) {
                            recursiveVarSearch(statement.program.inverse.statements, res, prefix + newprefix + (sideways ? (prefix + newprefix) ? "." + sideways : sideways : ""), helpersres);
                        }
                        recursiveVarSearch(statement.program.statements, res, prefix + newprefix + (sideways ? (prefix + newprefix) ? "." + sideways : sideways : ""), helpersres);
                    }
                });
                return res;
            }

            // This finds the Helper dependencies since it's soooo similar
            function getExternalDeps(nodes) {
                var res = [];
                var helpersres = [];

                if (nodes && nodes.statements) {
                    res = recursiveVarSearch(nodes.statements, [], undefined, helpersres);
                }

                var defaultHelpers = ["helperMissing", "blockHelperMissing", "each", "if", "unless", "with"];

                return {
                    vars: _(res).chain().unique().map(function(e) {
                        if (e === "") {
                            return '.';
                        }
                        if (e.length && e[e.length - 1] === '.') {
                            return e.substr(0, e.length - 1) + '[]';
                        }
                        return e;
                    }).value(),
                    helpers: _(helpersres).chain().unique().map(function(e) {
                        if (_(defaultHelpers).contains(e)) {
                            return undefined;
                        }
                        return e;
                    }).compact().value()
                };
            }

            function fetchAndRegister(langMap) {
                fetchText(path, function(text) {
                    // for some reason it doesn't include hbs _first_ when i don't add it here...
                    var nodes = Handlebars.parse(text),
                        deps = findPartialDeps(nodes),
                        meta = getMetaData(nodes),
                        extDeps = getExternalDeps(nodes),
                        vars = extDeps.vars,
                        helps = extDeps.helpers || [],
                        depStr = deps.join("', 'hbs!").replace(/_/g, '/'),
                        helpDepStr = config.hbs && config.hbs.disableHelpers ?
                        "" : (function() {
                            var i, paths = [],
                                pathGetter = config.hbs && config.hbs.helperPathCallback ? config.hbs.helperPathCallback : function(name) {
                                    return (config.hbs && config.hbs.helperDirectory ? config.hbs.helperDirectory : helperDirectory) + name;
                                };

                            for (i = 0; i < helps.length; i++) {
                                paths[i] = "'" + pathGetter(helps[i], path) + "'"
                            }
                            return paths;
                        })().join(','),
                        debugOutputStart = "",
                        debugOutputEnd = "",
                        debugProperties = "",
                        metaObj, head, linkElem;

                    if (depStr) {
                        depStr = ",'hbs!" + depStr + "'";
                    }
                    if (helpDepStr) {
                        helpDepStr = "," + helpDepStr;
                    }

                    if (meta !== "{}") {
                        try {
                            metaObj = JSON.parse(meta);
                            if (metaObj && metaObj.styles) {
                                styleList = _.union(styleList, metaObj.styles);

                                // In dev mode in the browser
                                if (require.isBrowser && !config.isBuild) {
                                    head = document.head || document.getElementsByTagName('head')[0];
                                    _(metaObj.styles).forEach(function(style) {
                                        if (!styleMap[style]) {
                                            linkElem = document.createElement('link');
                                            linkElem.href = config.baseUrl + devStyleDirectory + style + '.css';
                                            linkElem.media = 'all';
                                            linkElem.rel = 'stylesheet';
                                            linkElem.type = 'text/css';
                                            head.appendChild(linkElem);
                                            styleMap[style] = linkElem;
                                        }
                                    });
                                } else if (config.isBuild) {
                                    (function() {
                                        var fs = require.nodeRequire('fs'),
                                            str = _(metaObj.styles).map(function(style) {
                                                if (!styleMap[style]) {
                                                    styleMap[style] = true;
                                                    return "@import url(" + style + ".css);\n";
                                                }
                                                return "";
                                            }).join("\n");

                                        // I write out my import statements to a file in order to help me build stuff.
                                        // Then I use a tool to inline my import statements afterwards. (you can run r.js on it too)
                                        fs.open(__dirname + buildStyleDirectory + buildCSSFileName, filecode, '0666', function(e, id) {
                                            fs.writeSync(id, str, null, encoding = 'utf8');
                                            fs.close(id);
                                        });
                                        filecode = "a";
                                    })();
                                }
                            }
                        } catch (e) {
                            console.log('error injecting styles');
                        }
                    }

                    if (!config.isBuild && !config.serverRender) {
                        debugOutputStart = "<!-- START - " + name + " -->";
                        debugOutputEnd = "<!-- END - " + name + " -->";
                        debugProperties = "t.meta = " + meta + ";\n" +
                            "t.helpers = " + JSON.stringify(helps) + ";\n" +
                            "t.deps = " + JSON.stringify(deps) + ";\n" +
                            "t.vars = " + JSON.stringify(vars) + ";\n";
                    }

                    var mapping = disableI18n ? false : _.extend(langMap, config.localeMapping),
                        configHbs = config.hbs || {},
                        options = _.extend(configHbs.compileOptions || {}, {
                            originalKeyFallback: configHbs.originalKeyFallback
                        }),
                        prec = precompile(text, mapping, options);

                    text = "/* START_TEMPLATE */\n" +
                        "define(['hbs','handlebars'" + depStr + helpDepStr + "], function( hbs, Handlebars ){ \n" +
                        "var t = Handlebars.template(" + prec + ");\n" +
                        "Handlebars.registerPartial('" + name.replace(/\//g, '_') + "', t);\n" +
                        debugProperties +
                        "return t;\n" +
                        "});\n" +
                        "/* END_TEMPLATE */\n";

                    //Hold on to the transformed text if a build.
                    if (config.isBuild) {
                        buildMap[compiledName] = text;
                    }

                    //IE with conditional comments on cannot handle the
                    //sourceURL trick, so skip it if enabled.
                    /*@if (@_jscript) @else @*/
                    if (!config.isBuild) {
                        text += "\r\n//@ sourceURL=" + path;
                    }
                    /*@end@*/

                    for (var i in deps) {
                        if (deps.hasOwnProperty(i)) {
                            deps[i] = 'hbs!' + deps[i].replace(/_/g, '/');
                        }
                    }

                    if (!config.isBuild) {
                        require(deps, function() {
                            load.fromText(text);

                            //Give result to load. Need to wait until the module
                            //is fully parse, which will happen after this
                            //execution.
                            parentRequire([name], function(value) {
                                load(value);
                            });
                        });
                    } else {
                        load.fromText(name, text);

                        //Give result to load. Need to wait until the module
                        //is fully parse, which will happen after this
                        //execution.
                        parentRequire([name], function(value) {
                            load(value);
                        });
                    }

                    if (config.removeCombined) {
                        fs.unlinkSync(path);
                    }
                });
            }

            var path,
                omitExtension = config.hbs && config.hbs.templateExtension === false;
            if (omitExtension) {
                path = parentRequire.toUrl(name);
            } else {
                path = parentRequire.toUrl(name + '.' + (config.hbs && config.hbs.templateExtension ? config.hbs.templateExtension : templateExtension));
            }

            if (disableI18n) {
                fetchAndRegister(false);
            } else {
                // Workaround until jam is able to pass config info or we move i18n to a separate module.
                // This logs a warning and disables i18n if there's an error loading the language file
                var langMapPath = (config.hbs && config.hbs.i18nDirectory ? config.hbs.i18nDirectory : i18nDirectory) + (config.locale || "en_us") + '.json';
                try {
                    fetchOrGetCached(parentRequire.toUrl(langMapPath), function(langMap) {
                        fetchAndRegister(JSON.parse(langMap));
                    });
                } catch (er) {
                    // if there's no configuration at all, log a warning and disable i18n for this and subsequent templates
                    if (!config.hbs) {
                        console.warn('hbs: Error reading ' + langMapPath + ', disabling i18n. Ignore this if you\'re using jam, otherwise check your i18n configuration.\n');
                        config.hbs = {
                            disableI18n: true
                        };
                        fetchAndRegister(false);
                    } else {
                        throw er;

                    }
                }
            }
            //>>excludeEnd('excludeHbs')
        }
    };
});
/* END_hbs_PLUGIN */
