/**
 * General
 */ 

/**
 * Preloads a cache of images you can later retrive paths to by keys.
 *
 * eg:
 *
 *  $.imageCache('set path','/images/') // special call: set a base path to be used (or whatever you want to prepend).  You can 'set path' in an images object too.
 *  $.imageCache({'a':'long/path','b':'other/long/path'}); // preload images
 *  $.imageCache({'c':'more/long/path'}); // preload  more images
 *
 *  $.imagesCache('a'); // == 'long/path' // retieve image paths later
 */
$.imageCache = (function() { 
  var path = '';
  var images = {};
  return function(new_images)
  {
    if(new_images == 'set path') {
      path = new_images;
      return;
    }
    if(typeof new_images == 'object') {
      if(new_images['set path']) {
        path = new_images['set path'];
        delete new_images['set path'];
      }
      for(img in new_images)
      {
        var val = new_images[img];
        jQuery("<img>").attr("src", path+val);
        images[img] = path+val;
      }
      return;
    } else {
      return images[new_images];
    }
  };
})();

/**
 * Check if an object (or anything else) is "empty" or "false"
 * Shuold alwasy give t/f, never "undefined"
 */
$.isEmpty = function(obj) {
  var t = typeof(obj);
  if(t != 'object') {
    if(t=='undefined') return false;
    else return !obj; 
  }
  for(var i in obj){ if(obj.hasOwnProperty(i)){return false;}}
  return true;
}

/**
 * Turn link's href into calls to javascript functions.
 * "#" is optional, and everything before it will be ignored
 * Set 'root' in options, use "absolute paths" to override.
 *
 * eg href:
 * #alert/hello               // call "alert" with "hello"
 * #/console/log/hello/world  // call console.log with "hello" and "world"
 * /no-script-notice#alert/hi!       // you can use a no-script page in the link for degradation! :)
 */ 
$.fn.actionLinks = function(options) {
  options =$.extend({
    'root' : null
  }, options);

  (function(options) {
    $(this.selector).live('click', function(e) {
      e.preventDefault();
      var action; // look for action here, or in first contained link
      action = $(this).attr('href');
      $.callLinkAction(action, options.root);
    });
  }).call(this,options);
};

/**
 * Used by actionLinks, but handy to allow your own events to 
 * call "link string functions"  the same way.
 */ 
$.callLinkAction = function(action,root) {
  action = action.split('#');
  action = action.pop();
  obj = root || window;
  if(action.indexOf('/')==0) {
   action = action.split('/').slice(1);
   obj = window[action.shift()];
  } else {
   action = action.split('/');
  }
 fnc = action.shift();
 args = action;
 RAOS.log('Action Link:', obj, fnc, args);
 return obj[fnc].apply(obj,args);
};

// Add stuff to wishlist or shopping cart.
baskets = {
  addToCart: function(type, sku) {
    this.addToBasket(sku,'/shop/cart/add/'+type,'Item Added To Your Cart','#shopping_cart_count');
  },
  addToWishList: function(type, sku) {
    this.addToBasket(sku,'/shop/wishlist/add/'+type,'Item Added To Your Wishlist','#wish_list_count');
  },
  lastID : null, // this is a bit risky (See below), but quick at the time and should work most of the time.
  addToBasket: function(sku,url, msg,elsel) {
    (function() {
      baskets.lastID = uuid();
      $.ajax( 
      { url : url,
        type: 'post',
        data: {'sku':sku,'id':baskets.lastID},
        success: function(data) {
          var cart = eval('['+data+']').pop(); 
          for(var i = 0; i < cart.length; i++) if(cart[i]['id']==baskets.lastID) recomm = cart[i]['recommends'];
          if(recomm) {
            recomm_txt = [];
            recomm = recomm.pop(); // just use the first matching rule for now...
            for(var i = 0; i < recomm.length; i++) {
              recomm_txt.push('<a href="'+recomm[i]['url']+'">'+recomm[i]['display']+'</a>');
            }
            recomm_txt = recomm_txt.join(' or ');
            recomm_txt = '<div class="msg-suggest">Would you also like to see a '+recomm_txt+'?</div>';
            feedback.ask(msg,recomm_txt);
          } else {
            feedback.display(msg);
          }
          $(elsel).html(cart.length);
        } 
      });
    })();
  }
};

/**
 * CADI
 */ 
$(function() {
  //if(window.location.pathname == '/go') enableHijax();
  $('.hinter').hinter(); 
  makeBannerLinks();
  $('.act-link').actionLinks();
  $.imageCache(
    {
      'set path': '/img/',
      'search on' : 'btn-search-diamonds-on.jpg',
      'search off' : 'btn-search-diamonds-off.jpg',
	  'learn on' : 'btn_learn_more_on.jpg',
      'learn off' : 'btn_learn_more_off.jpg',
	  'start on' : 'btn_start_on.jpg',
      'start off' : 'btn_start_off.jpg',
	  'view on' : 'btn_view_on.jpg',
      'view off' : 'btn_view_off.jpg',
	  'viewcart on' : 'btn_view_cart_on.jpg',
      'viewcart off' : 'btn_view_cart_off.jpg',
	  'movecart on' : 'btn_move_to_cart_on.jpg',
      'movecart off' : 'btn_move_to_cart_off.jpg',
      'add cart on' : 'btn_add_cart_on.jpg',
      'add cart off' : 'btn_add_cart_off.jpg',
      'add wishlist on' : 'btn_add_to_wishlist_on.jpg',
      'add wishlist off' : 'btn_add_to_wishlist_off.jpg',
      'return to search off' : 'btn_return_to_search_off.jpg',
      'return to search on' : 'btn_return_to_search_on.jpg',
      'change off' : 'btn_change_off.jpg',
      'change on' : 'btn_change_on.jpg',
      'place order on' : 'btn_place_my_order_on.jpg',
      'place order off' : 'btn_place_my_order_off.jpg',
      'rsvp off' : 'btn_submit_rsvp_off.jpg',
      'rsvp on' : 'btn_submit_rsvp_on.jpg',
      'return to search on' : 'btn_return_to_search_on.jpg',
      'return to search off' : 'btn_return_to_search_off.jpg',
      'add to ring on' : 'btn_add_to_ring_on.jpg',
      'add to ring off' : 'btn_add_to_ring_off.jpg',
      'add to diamond off' : 'btn_add_to_diamond_off.jpg',
      'add to diamond on' : 'btn_add_to_diamond_on.jpg',
      'send request on' : 'btn_send_request_on.jpg',
      'send request off' : 'btn_send_request_off.jpg'
    }
  );

  $('.thumbnail').click(function(){
    $('#prod_detail_img').css({'backgroundImage':'url("'+$.imageCache($(this).find('img').attr('src'))+'")'});
  });

  $('body').commonEvents();

  $('.submit').click(function(e) {
    e.preventDefault();
    $(this).closest('form').submit();
  });
  // merge (^) these (V) two functions into one for future projects.
  $('.submit-href').click(function(e) {
    e.preventDefault();
    $(this).closest('form').attr('action', $(this).attr('href')).submit();
  });

  /* coming soon stuff, can be removed when done */
  $('a[href="/comingSoon"], a[href="#"], a[href^="/tmp/"]').click(function(e) {
   e.preventDefault(); 
   var link = $(this).attr('title') || $(this).text();
   var msg = link ? "The page for \""+link+"\" is under construction" : "The page for that link is under construction";
   feedback.say("Coming Soon", msg);
  }).addClass('missing');
  if($('#inventory_page').length) {
    feedback.say('Inventory Coming Soon','These inventory pages are under construction.');
  }
});

$.fn.commonEvents = function() {
  $(this)
    .find('.rollover,.rollover img').hover(
      function() {
        $(this).attr('src',$.imageCache($(this).attr('alt')+' on'));
      },
      function() {
        $(this).attr('src',$.imageCache($(this).attr('alt')+' off'));
      }
    );
  return this;
}

/**
 * Make banners clickable based on link found inside. 
 */ 

function makeBannerLinks() {
  $('.banner-link').each(function() {
    var href = $(this).attr('href');
    $(this).closest('.banner').css({'cursor':'pointer'}).click(function() {
      window.location = href;
    });
  });
}

/**
 * Ajax Content Page Loads
 */

// tmp hack to manage images by imageLoaded
var img_cnt = 0;
var flipflop = true;
var cur_target = '';

// called by jquery.history_remote
function ajax_link_click() {
  // hold size until loaded
  $('#page_content_container').css({'height':$('#page_content_container').height()+'px',overflow:'hidden'});
  flipflop = !flipflop;
  
  $cur_target = $(flipflop ? '#page_content' : '#page_content_2');
  return $cur_target;
}
/* resize content after all images load... or after a set timeout */
// debug
var imgtest = {};
function ajax_link_loaded() {
  imgtest = {};
  var $imgs = $cur_target.find('img');
  img_cnt = $imgs.length;

  $imgs.each(function() {
    imgtest[$(this).attr('src')] = 1;
  });

  $('.page-content').css({'height':'auto','width':'auto'});
  if(img_cnt) {
    $cur_target.find('img').load(imageLoaded);
    setTimeout(function(){resizeContent('timed out')},1000); 
  } else resizeContent('instant');
  RAOS.log('slide next');
  $('#page_content_container').cycle('next');
}
function imageLoaded() {
  img_cnt--;
  delete imgtest[$(this).attr('src')];
  if(img_cnt == 0) resizeContent('images loaded');
}
function resizeContent(msg) {
  // cycle plugin tries to control page
  $('.page-content').css({'height':'auto','width':'auto'});
  if(msg=='timed out') {
    //feedback.say('Timed Out');
    RAOS.log(imgtest);
  }
  $('#page_content_container').animate({'height':$cur_target.height()},'slow');
}

/**
 * Enable ajax page loading 
 */ 
function enableHijax() {
  // todo: we can do a better remote function
  $('#page_content_container')
    .append($('#page_content').clone().attr('id', 'page_content_2'))
    .cycle({timeout:0});

  // all ajax request should be made on the "go document".  Otherwise, set links up to go there.
  if(window.location.pathname != '/go') {
    $('.ajax-page-links').find('a').each(function() {
      $(this).attr('href', '/go#'+$(this).attr('href'));
    });
  } else 
    $('.ajax-page-links').find('a').remote($('#page_content').get(0),null,ajax_link_loaded,ajax_link_click);

  $.ajaxHistory.initialize();
}

/**
 *  Makes inputs in selection (or those found as children) 
 *  show 'Title' attribute as "hint".
 *  Applies hard-coded styles
 */ 
$.fn.hinter =  function() {
  var $selection;
  if(!($selection =  $(this).filter('input[title]')).length)
    if(!($selection = $(this).find('input[title]')).length)
      { return this;}


  
  function hint_on($t) {
      if($t.data('hint_on')) return;
      if($t.val()!='') return;
      $t.css({color:'#AABBCD', fontStyle:'italic'})
        .data('hint_on',true)
        .val($t.attr('title'));
  }
  function hint_off($t) {
    if(!$t.data('hint_on')) return;
    $t.css({color:'#222222', fontStyle:'normal'})
      .data('hint_on',false)
      .val('');
  }

  $selection.blur( function() { hint_on($(this)); })
            .focus( function() { hint_off($(this));})
            .blur(); // call blur to set intial hint

  if(!$.fn.orginal_val) {
    $.fn.orginal_val = $.fn.val;
    $.fn.val = function(val) {
      if(!(typeof(val)=='undefined')) return $(this).orginal_val(val);  
      out = $(this).orginal_val();
      if(out == $(this).attr('title')) return '';
      else return out;
    };
  }


  return this;
}
/**
 * RFC-4122 ver 4 UUIDs
 */
function uuid() {

  var s = [], hex = '0123456789ABCDEF';

  for (var i = 0; i <36; i++) s[i] = Math.floor(Math.random()*0x10);

  // as per RFC-4122/4.4 ...
  s[14] = 4;  // Set 4 high bits of time_high field to version
  s[19] = (s[19] & 0x3) | 0x8;  // Specify 2 high bits of clock sequence

  for (var i = 0; i <36; i++) s[i] = hex[s[i]];
  s[8] = s[13] = s[18] = s[23] = '-';
  return s.join('');
}
