// An Item is an instance of a Cheese or a Sandwhich
var Item = function(json_obj) {
  var this_item = new Object();
  
  // Add all of the attributes from the XML
  for (prop in json_obj) {
    if (prop.indexOf('@') === 0) {
      this_item[prop.substr(1)] = json_obj[prop];
    }
  }
  
  // Add directions if present
  if (json_obj['directions']) {
    this_item['directions'] = json_obj['directions']['#cdata'];
  }
  
  if (json_obj['pdf']) {
    this_item['pdf'] = json_obj['pdf'];
  }  
  
  if (json_obj['twitter']) {
  	this_item['twitter'] = json_obj['twitter'];
  }
  
  // Add ingredients if present
  if (json_obj['ingredients']) {
    this_item['ingredients'] = [];
    var ingredients_count = json_obj['ingredients']['ingredient'].length;
    var i = 0;
    for (i = 0; i < ingredients_count; i++) {
      this_item['ingredients'].push(json_obj['ingredients']['ingredient'][i]);
    }
  }
  
  // Add relations if present
  if (json_obj['relations']) {
    this_item['relations'] = [];
    if(json_obj['relations']['relation'].length != undefined){
	    var relations_count = json_obj['relations']['relation'].length;
	}else if(json_obj['relations']['relation']){ //force non-array->array
		var relations_count = 1;
		json_obj['relations']['relation'] = [json_obj['relations']['relation']];
	}else{
		var relations_count = 0;
	}

    var i = 0;
    for (i = 0; i < relations_count; i++) {
      this_item['relations'].push(json_obj['relations']['relation'][i]['@name']);
    }
  }
  
  // Callback to flag/signal that a particular image is loaded
  var imgLoaded = function(cfg, loaded_item) {
    return function(data, textStatus) {
      cfg['loaded'][loaded_item] = true;
      if (typeof loaded_callback === 'function') {
        loaded_callback(loaded_item, cfg);
      }
      if (typeof cfg[loaded_item + '_callback'] === 'function') {
        cfg[loaded_item + '_callback'](loaded_item, cfg);
      }
    };
  } // imgLoaded()
  
  this_item['loaded'] = [];

  if ('thumb' in this_item) {
    this_item['loaded']['thumb'] = false;
    this_item['thumb_img'] = new Image();
  }

  if ('medium' in this_item) {
    this_item['loaded']['medium'] = false;
    this_item['medium_img'] = new Image();
  }
  
  if ('detail' in this_item) {
    this_item['loaded']['detail'] = false;
    this_item['detail_img'] = new Image();
  }
  
  if ('mp3audio' in this_item) {
    this_item['loaded']['mp3audio'] = false;
  }
  
  if ('oggaudio' in this_item) {
    this_item['loaded']['oggaudio'] = false;
  }
  
  // add a load method for thumb images if present
  if (this_item['thumb']) {
    this_item['loadThumb'] = function() {
      try {
        if (typeof arguments[0] === 'function') {
          this_item['thumb_callback'] = arguments[0];
        }
        this_item['thumb_img'].onload = imgLoaded(this_item, 'thumb');
        this_item['thumb_img'].src = this_item['thumb'];
        $(this_item['thumb_img']).attr('alt', this_item['label']).addClass('thumbnail_image, ' + this_item['type'] + '_image, ' + this_item['name']);
        delete this_item['loadThumb'];
      } catch (ex) {
        //dbgMsg('ERROR: ' + ex.name + ' -- ' + ex.message + ' at line number ' + ex.lineNumber);
      }
    }
  }
  
  // add a load method for medium images if present
  if (this_item['medium']) {
    this_item['loadMedium'] = function(){
      try {
        if (typeof arguments[0] === 'function') {
          this_item['medium_callback'] = arguments[0];
        }
        this_item['medium_img'].onload = imgLoaded(this_item, 'medium');
        this_item['medium_img'].src = this_item['medium'];
        $(this_item['thumb_img']).attr('alt', this_item['label']).addClass('medium_image, ' + this_item['type'] + '_image, ' + this_item['name']);
      } catch (ex) {
        //dbgMsg('ERROR: ' + ex.name + ' -- ' + ex.message + ' at line number ' + ex.lineNumber);
      }
    }
  }
  
  // add a load method for detail images if present
  if (this_item['detail']) {
    this_item['loadDetail'] = function(){
      try {
        if (typeof arguments[0] === 'function') {
          this_item['detail_callback'] = arguments[0];
        }
        this_item['detail_img'].onload = imgLoaded(this_item, 'detail');
        this_item['detail_img'].src = this_item['detail'];
        $(this_item['thumb_img']).attr('alt', this_item['label']).addClass('detail_image, ' + this_item['type'] + '_image, ' + this_item['name']);
        delete this_item['loadDetail'];
      } catch (ex) {
        //dbgMsg('ERROR: ' + ex.name + ' -- ' + ex.message + ' at line number ' + ex.lineNumber);
      }
    }
  }
  
  this_item['loadRelationsThumbs'] = function() {
    var relation_callback = function() { };
    if (typeof arguments[0] === 'function') {
      relation_callback = arguments[0];
    }
    var rel_lookup = this_item['type'] === 'cheese' ? Sandwiches : Cheeses;
    for (l = 0; l < this_item['relations'].length; l++) {
      var rel = this_item['relations'][l];
      if (rel_lookup.hasItem(rel)) {
        var related_item = rel_lookup.getItem(rel);
        if (!related_item.isLoaded('thumb')) {
          related_item.loadThumb(relation_callback);
        }
      }
    }
  } // loadRelationsThumbs()
  
  this_item['isLoaded'] = function(resource) {
    return (this_item['loaded'] && this_item['loaded'][resource]);
  } // isLoaded()

  this_item['getAudio'] = function() {
    if (AudioSupport.Flash()) {
      return this_item['mp3audio'];
    } else if (AudioSupport.HTML5()) {
      return this_item['oggaudio'];
    } else {
      return '';
    }
  } // getAudio()

  return this_item;
} // Item "class"

/****************************************************************************************************/
/****************************************************************************************************/
/****************************************************************************************************/

// An ItemContainer is a glorified array of
// cheese -xor- sandwiches with a few helper methods
// tacked on
var ItemContainer = function(type) {
  this._type = type;
  this._items = {};
  
  this.addItem = function(item) {
    this._items[item['name']] = item;
    if(typeof item['number'] !== 'undefined') {
    	this._items[item['number']] = item;
    }
  } // addItem()
  
  this.hasItem = function(name) {
    return (typeof this._items[name] !== 'undefined');
  } // hasItem()
  
  this.hasNumber = function(number) {
  	return (typeof this._items[number] !== 'undefined');
  }
  
  this.getItem = function(name) {
    if (this.hasItem(name)) {
      return this._items[name];
    } else {
      return {};
    }
  } // getItem()
  
  this.getItemByNumber = function(number) {
  	if (this.hasNumber(number)) {
  		return this._items[number];
  	} else {
  		return {};
  	}
  }
  
  this.parseXML = function(xml_str) {
    var dom = null;
    if (window.DOMParser) {
      try { 
         dom = (new DOMParser()).parseFromString(xml_str, "text/xml"); 
      } catch (e) {
        //dbgMsg('Error DOMParser: ' + e);
        dom = null;
      }
    } else if (window.ActiveXObject) {
      try {
        dom = new ActiveXObject('Microsoft.XMLDOM');
        dom.async = false;
        if (!dom.loadXML(xml_str)) {
          //dbgMsg(dom.parseError.reason + " --- " + dom.parseError.srcText);
        }
      } catch (e) {
        //dbgMsg('Error Microsoft.XMLDOM' + e);
        dom = null;
      }
    } else {
      // dbgMsg("oops");
    }
    return dom;
  } // parseXML()
  
  this.processXML = function(xml_str) {
    var xml = this.parseXML(xml_str);
    
    var json_str = xml2json(xml, '');
    var json = eval('(' + json_str + ')');
    var item_cnt = json['items']['item'].length;
    var i = 0;
    for (i = 0; i < item_cnt; i++) {
      var item = json['items']['item'][i];
      var new_item = Item(item);
      this.addItem(new_item);
    }    
  } // processXML()
  
  this.items = function() {
    return this._items;
  } // items()
  
  this.each = function(func) {
    for (item_name in this._items) {
      func(this._items[item_name]);
    }
  } // each()
  
  return this;
} // ItemContainer "class"

