var imgLoader = function(ctx) {
  var context     = ctx,
      loadCount   = 0,
      toBeLoaded  = 0,
      imgHashes   = {},
      theImages   = null,
      loading     = false,
      doneLoading = false,
      onloadCallback,
      doneLoadingCallback;

  var imgHashes = function() {
    return imgHashes;
  };

  var images = function() {
    if(!doneLoading) {
      return null;
    }

    if(theImages) {
      return theImages;
    }

    theImages = {};
    eachImg(function(name, image) {
      theImages[name] = image;
    })
    return theImages;
  }

  var push = function(imgName, url) {
    img = new Image();
    src = url;
    if(!imgHashes[imgName]) {
      toBeLoaded += 1;
    } else {
      console.log("ERROR: " + imgName + " already taken as an image name");
      return;
    }
    imgHashes[imgName] = {img: img, src: src};
  };

  var startLoading = function(doneLoadingCB, onloadCB) {
    eachHash(function(key, hash) {
      var img = hash.img;
      img.src = hash.src;
      img.onload = imgLoaded;
    });

    loading = true;
    onloadCallback = onloadCB;
    doneLoadingCallback = doneLoadingCB;
  };

  var imgLoaded = function() {
    loadCount += 1;
    onloadCallback();
    if(loadCount >= toBeLoaded) {
      loading = false;
      doneLoading = true;
      if(doneLoadingCallback) {
        doneLoadingCallback();
      };
    }
  }

  var eachHash = function(fn) {
    for(var imgName in imgHashes) {
      var obj = imgHashes[imgName];
      fn(imgName, obj);
    }
  };

  var eachImg = function(fn) {
    eachHash( function(imgName, imgHash) {
      fn(imgName, imgHash.img);
    });
  };

  return {
    startLoading:  startLoading,
    imgHashes:     imgHashes,
    push:          push,
    eachHash:      eachHash,
    eachImg:       eachImg,
    images:        images,
    toBeLoaded:    function() { return toBeLoaded; },
    loadCount:     function() { return loadCount;  }
  };
};



