'use strict';

var domready = require('domready');

var graphicsModule = require('codehs-graphics');
var dataStructuresModule = require('codehs-datastructures');
var consoleModule = require('codehs-console');
var randomizerModule = graphicsModule.Randomizer;

// This is the insertion point for the distributed JS library.
var CodeHSGraphics = graphicsModule.CodeHSGraphics;
var CodeHSConsole = consoleModule.CodeHSConsole;
var CodeHSDatastructures = dataStructuresModule;

if (window) {
    var PUBLIC_METHODS = {};
    var PUBLIC_CONSTRUCTORS = {};

    PUBLIC_METHODS.__graphics__ = graphicsModule.PUBLIC_METHODS;
    PUBLIC_METHODS.__console__ = consoleModule.PUBLIC_METHODS;

    PUBLIC_CONSTRUCTORS.__graphics__ = graphicsModule.PUBLIC_CONSTRUCTORS;
    // everything in the datastructures module is a constructor for a data struct.
    PUBLIC_CONSTRUCTORS.__datastructs__ =
        dataStructuresModule.PUBLIC_CONSTRUCTORS;

    // Make a wrap of all namespaced methods
    var makeNamespaceWrap = function() {
        var result = '';
        var namespace;
        var method;
        var i;
        for (namespace in PUBLIC_METHODS) {
            if (PUBLIC_METHODS.hasOwnProperty(namespace)){
                for (i = 0; i < PUBLIC_METHODS[namespace].length; i++) {
                    method = PUBLIC_METHODS[namespace][i];
                    result += "window." + method + " = " +
                              "function(){\n\treturn " + namespace + "." +
                              method + ".apply(" +
                              namespace + ", arguments);\n}\n";
                }
            }
        }

        var constructor;
        for (namespace in PUBLIC_CONSTRUCTORS) {
            if (PUBLIC_CONSTRUCTORS.hasOwnProperty(namespace)) {
                for (i = 0; i < PUBLIC_CONSTRUCTORS[namespace].length; i++) {
                    constructor = PUBLIC_CONSTRUCTORS[namespace][i];
                    result += "window." + constructor +
                    " = " + namespace + "." + constructor + ";\n";
                }
            }
        }

        return result;
    };

    var setup = function() {
        // Attach libaries to the window as constants
        window.__graphics__ = new CodeHSGraphics();
        window.__console__ = new CodeHSConsole();
        window.__datastructs__ = CodeHSDatastructures;

        // Also need a CodeHSGraphics constructor to make multiple instances
        window.CodeHSGraphics = CodeHSGraphics;

        // Attach other modules to the window
        window.Randomizer = randomizerModule;
        window.Color = graphicsModule.Color;
        var wrap = makeNamespaceWrap();
        eval(wrap);
    };

    domready(function() {
        setup();
    });
};

module.exports = {
    CodeHSGraphics: CodeHSGraphics,
    CodeHSConsole: CodeHSConsole,
    CodeHSDatastructures: CodeHSDatastructures
};
