function A3K_hash_length(arr) {
  count = 0;
  for (var x in arr) { count++; }
  return count;
}

function A3K_CDNDetector(type, artifactUrl, urls, onDetect) {
  var self = this;

  self.type = type;
  self.artifactUrl = artifactUrl;
  self.urls = urls;
  self.currentIndex = 0;
  self.maxIndex = urls.length;
  self.detectionComplete = false;
  self.detectedIndex = null;

  self.detect_cdn = function() {
    self.do_detect_cdn();
  }

  self.record_response = function(index, success) {
    if (success) {
      self.detectedIndex = index;
      self.detectionComplete = true;
    }
    else {
      if (self.currentIndex + 1 < self.maxIndex) {
        self.currentIndex++;
        return self.do_detect_cdn();
      }
      else {
        self.detectionComplete = true;
      }
    }

    if (onDetect === null) { return; }
    onDetect(self.type, self.cdnIndex(), self.cdn());
  }

  self.do_detect_cdn = function() {
    url = self.urls[self.currentIndex];
    image = new Image();
    image.onload =  function() { self.record_response(self.currentIndex, true);  };
    image.onerror = function() { self.record_response(self.currentIndex, false); };
    image.src = url + self.artifactUrl;
  }

  self.cdnIndex = function() {
    return self.detectedIndex;
  }

  self.cdn = function() {
    if (self.detectedIndex === null) {
      return null;
    }

    return self.urls[self.detectedIndex];
  }
}

function A3K_CDNDetectorCatalog(artifactUrl, configuration, onDetect) {
  var self = this;

  self.artifactUrl = artifactUrl;
  self.configuration = configuration;
  self.onDetect = onDetect;
  self.configurationLength = A3K_hash_length(self.configuration)
  self.cdnDetectors = new Array();
  self.results = {};

  self.recordResult = function(key, index) {
    self.results[key] = index;

    if (A3K_hash_length(self.results) === self.configurationLength) {
      urls = {};
      for (var key in self.results) {
        urls[key] = self.configuration[key][self.results[key]];
      }

      self.onDetect(self.results, urls);
    }
  }

  self.detect_cdn = function() {
    for (key in self.cdnDetectors) {
      self.cdnDetectors[key].detect_cdn();
    }
  }

  // Initialize
  for (var key in self.configuration) {
    self.cdnDetectors[key] = new A3K_CDNDetector(key, self.artifactUrl, configuration[key], function(type, index, url) {
      self.recordResult(type, index);
    });
  }
}


