var ProductManager = function() {
  
  var methods = {};
  var products = [];
  
  function init() {
    
  }
  
  function add(product) {
    products.push(product)
  }
  
  function list() {
    return products;
  }
  
  function get_by_code(code) {
    for (var i = 0; i < products.length; i++) {
      var product = products[i];
      if (product.code == code) {
        return product;
      }
    }
    
    return false;
  }
  
  function get_by_codes(codes) {
    var out = [];
    for (var i = 0; i < codes.length; i++) {
      var code = codes[i];
      var product = get_by_code(code);
      if (product) out.push(product);
    }
    
    return out;
  }
  
  function get_by_indexes(indexes) {
    var out = [];
    for (var i = 0; i < indexes.length; i++) {
      var index = indexes[i];
      out.push(products[index]);
    }
    
    return out;
  }
  
  function get_by_filter(filter) {
    if (filter == 'all') return list();
    
    var out = [];
    for (var i = 0; i < products.length; i++) {
      var product = products[i];
      if (product.filter == filter) {
        out.push(product);
      }
    }
    
    return out;
  }
  
  init();
  
  methods.add = add;
  methods.list = list;
  methods.get_by_code = get_by_code;
  methods.get_by_codes = get_by_codes;
  methods.get_by_indexes = get_by_indexes;
  methods.get_by_filter = get_by_filter;
  return methods;
  
}

var build_product = function(product) {
  var thumb_1 = $('<img/>').addClass('one').attr({src: product.thumb_1, width: 218, height: 160});
  var thumb_2 = $('<img/>').addClass('two').attr({src: product.thumb_2, width: 218, height: 160});

  // thumb_1 = $('<div>').addClass('one').append(thumb_1);
  // thumb_2 = $('<div>').addClass('two').append(thumb_2);

  var caption = $('<div/>').addClass('caption');
  var caption_contents = $('<p>');
    
  var caption_title = $('<strong/>').html('<span class="title">' + product.title_truncated + '</span><br>' + product.artist_truncated);
  caption.append(caption_title);
  
  caption.append($('<br/>'));

  var caption_details = $('<span/>').addClass('arrowed').text('More details');
  caption.append(caption_details);
  
  // caption.append(caption_contents);

  var out = $('<div/>').addClass('product-dynamic').addClass('loading').addClass('product-dynamic-spinning');
  if (product.precious) {
    out.addClass('product-dynamic-precious');
  }
  
  var shim = $('<div/>').addClass('shim');
  
  shim.hover(hover_in, hover_out);
  out.append(caption).append(shim).append(thumb_1).append(thumb_2);
  out.imagesLoaded(loaded);

  // out.click(function() { document.location.href = '/collection/product/' + product.code });

  return out;
}

var show_products = function(_products) {
  for (var i = 0; i < _products.length; i++) {
    var product = _products[i];

    var product_el = build_product(product);
    var x = (i % 4) * 240;
    var y = Math.floor(i / 4) * 180;
    var style = {top: px(y), left: px(x + 36), opacity: 0};
    product_el.css(style);
    on_show.push(product_el);
    
    (function(i, product_el, product) {
      product_el.click(function() { expand_product(i, product)});
      setTimeout(function() {
        product_el.appendTo(container).animate(
          { opacity: 1},
          500
        );
        }, 
        (i * 100) + 500
      );
    })(i, product_el, product);

    container.append(product_el);
  }
  
  var new_height = Math.ceil(_products.length / 4) * 180;
  container.animate({height: px(new_height)}, 500);
  
};

var hide_products = function() {
  
  if (currently_expanded != null) {
    contract_product();
  }
  
  $('#no-results').animate({opacity: 0});
  
  for (var i = 0; i < on_show.length; i++) {
    var el = on_show[i];

    (function(i, el) {
      setTimeout(function() {
 
        el.stop(true, true).animate({opacity: 0}, 500, function() {
          $(this).remove();
        })
      },
      i * 100)
    })(i, el);
  
  }
 
  on_show = [];
}

var change_filter = function(filter) {
  current_products = products.get_by_filter(filter)
  current_page = 0;
  total_pages = Math.ceil(current_products.length / ITEMS_PER_PAGE);
  
  hide_products();
  show_products(current_products.slice(0, ITEMS_PER_PAGE));
  update_page_display();
  update_heading(nice_category[filter]);
}

var change_page = function(direction) {
  var new_page = current_page + direction;
    
  if (new_page < 0 || new_page >= total_pages) return;
  
  current_page = new_page;
  var offset = current_page * ITEMS_PER_PAGE;
  
  hide_products();
  show_products(current_products.slice(offset, offset + ITEMS_PER_PAGE));
  update_page_display();
}

var update_page_display = function() {

  $('#products-page').text('Page ' + (current_page + 1) + ' of ' + total_pages)

  var v = (total_pages == 0) ? 'hidden' : 'visible';
  $('#products-page').css({visibility: v});

  v = (current_page == 0 || total_pages == 0) ? 'hidden' : 'visible';
  $('#products-previous').css({visibility: v});    

  v = (current_page + 1 == total_pages || total_pages == 0) ? 'hidden' : 'visible';
  $('#products-next').css({visibility: v});
  
}

var search_complete = function(data, query) {
  stop_spinner();
  
  var results = data.results;

  if (results.length == 0) {
    current_products = [];
    total_pages = 0;
    
    update_page_display();
    update_heading('No search results for: "' + query + '"');
    hide_products();

    setTimeout(function() {
      $('#no-results').animate({opacity: 1});
    }, 500);

    container.animate({height: px(180)}, 500);

    return;
  }
    
  var _products = [];
  
  for (var i = 0; i < results.length; i++) {
    var result = results[i];
    _products.push(products.get_by_code(result));
  }
  
  current_products = _products;
  current_page = 0;
  total_pages = Math.ceil(current_products.length / ITEMS_PER_PAGE);
  
  hide_products();
  show_products(current_products.slice(0, ITEMS_PER_PAGE));
  update_page_display();
  update_heading('Search results for: "' + query + '"');
} 

var update_heading = function(text) {
  $('#collection-heading').text(text);
}

var expand_product = function(index, product) {
  var expanding_row = Math.floor(index / 4);
  var expanded_row = 100;

  if (index === currently_expanded) {
    contract_product();
    return;
  }
  
  if (currently_expanded != null) {
    expanded_row = Math.floor(currently_expanded / 4);
    var el = on_show[currently_expanded];
    el.removeClass('product-dynamic-expanded');
  }
  
  var expander = expanders.eq(expanding_row);
  var product_el = on_show[index];
  
  product_el.addClass('product-dynamic-expanded');
  product_el.find('.caption').stop(true, false).animate({top: px(160)}, 300);
 
  var arrow_x = (index % 4) * 240 + 128;
    
  if (expanded_row == expanding_row) {
    currently_expanded = index;
    expander.find('.expander-arrow').animate({left: px(arrow_x)}, 300);

    expander.find('.expander-fade')
            .animate({opacity: 0}, 200);

    setTimeout(function() {
      expander.find('h2').text(product.title);
      expander.find('h3').text(product.artist);
      expander.find('.materials').html(product.materials);
      expander.find('.description').text(product.description);
      
      var i = product_el.hasClass('flipped') ? product.thumb_1 : product.thumb_2;
      var thumb = $('<img/>').attr({width: 360, height: 265, src: i});
      
      expander.find('.expander-image-container').html(thumb);
      expander.find('a').attr({href: product.url});
      
      expander.find('.expander-fade')
              .animate({opacity: 1}, 200);
      
    }, 210);
    
    return; 
  }

  expander.find('h2').text(product.title);
  expander.find('h3').text(product.artist);
  expander.find('.materials').html(product.materials);
  expander.find('.description').text(product.description);
  
  var i = product_el.hasClass('flipped') ? product.thumb_1 : product.thumb_2;
  var thumb = $('<img/>').attr({width: 360, height: 265, src: i});

  expander.find('.expander-image-container').html(thumb);
  expander.find('a').attr({href: product.url});
  
  // expander.unbind('click');
  // expander.click(function() { document.location.href = product.url});

  expander.find('.expander-arrow').css({left: px(arrow_x)});
  
  for (var i = 0; i < on_show.length; i++) {
    var row = Math.floor(i / 4);
    var y = row * 180;
    if (row > expanding_row) y += 355;
    
    var el = on_show[i];
    
    el.stop(true, false).css({opacity: 1}).animate({top: px(y)}, 500);
  }
  
  var top = expanding_row * 180 + 162;
  var new_top = top;
  if (expanding_row > expanded_row) top += 355;
  expander.css({top: px(top)});
  expander.stop(true, false).animate({top: px(new_top), height: px(355)}, 500);
  
  if (currently_expanded != null) {
    var new_top = expanded_row * 180 + 162;
    if (expanded_row > expanding_row) new_top += 355;
    expanders.eq(expanded_row).stop(true, false).animate({height: 0, top: px(new_top)}, 500);
  }
  
  var new_height = Math.ceil(on_show.length / 4) * 180;
  container.stop(true, false).animate({height: px(new_height + 355)}, 500);

  currently_expanded = index;
}

var contract_product = function() {
  if (currently_expanded == null) return;
  
  var product_el = on_show[currently_expanded];
  product_el.removeClass('product-dynamic-expanded');

  for (var i = 0; i < on_show.length; i++) {
    var row = Math.floor(i / 4);
    var y = row * 180;
    var el = on_show[i];
    el.stop(true, false).animate({top: px(y)}, 400);
  }
  
  expanded_row = Math.floor(currently_expanded / 4);
  expanders.eq(expanded_row).stop(true, false).animate({height: 0}, 400);
  
  var new_height = Math.ceil(on_show.length / 4) * 180;
  container.stop(true, false).animate({height: px(new_height)}, 400);
  
  currently_expanded = null;
}

// Bound product events

var loaded = function() {

  var el = $(this);
  el.removeClass('loading');
  
  // if ($.support.opacity) {
    el.find('.one').animate({opacity: 1}, 500);
  // }
  
  el.find('.caption').animate({top: px(160)}, 500);

  setTimeout(function() { el.removeClass('product-dynamic-spinning')}, 500);
}

var hover_in = function() {
  var el = $(this).parent('.product-dynamic');
  if (el.hasClass('loading')) return;
  if (el.hasClass('product-dynamic-expanded')) return;

  // alert('in');
  
  if ($.browser.msie) {
    el.find('.caption').css({top: px(71)});
  }
  else {
    el.find('.caption').animate({top: px(71)}, 300);        
  }
  
}

var hover_out = function() {
  var el = $(this).parent('.product-dynamic');
  if (el.hasClass('loading')) return;
  if (el.hasClass('product-dynamic-expanded')) return;

  el.find('.caption').animate({top: px(160)}, 300);
  
  if (el.hasClass('flipped')) {
    el.find('.two').animate({opacity: 0}, 250);
    el.find('.one').delay(170).animate({opacity: 1}, 250);
    el.removeClass('flipped');
  }
  else {
    el.find('.one').animate({opacity: 0}, 250);
    el.find('.two').delay(170).animate({opacity: 1}, 250);
    el.addClass('flipped');
  }
  
}


