/*-----------------------------*/
/* Yugambeh (The Drumley Walk) */
/*-----------------------------*/

// establish shortcut functions 
// which can be used in link hrefs
function ygm__lb_terms_of_use(){
  var lb = $('#ygm-embedded-terms-of-use-lightbox .ygm-titled-text-lightbox').clone(true);
  if (!lb.size()) return;
  plb__lightbox.open(lb);
}
function ygm__lb_privacy_policy() {
  var lb = $('#ygm-embedded-privacy-policy-lightbox .ygm-titled-text-lightbox').clone(true);
  if (!lb.size()) return;
  plb__lightbox.open(lb);
}
function ygm__lb_indemnity_and_privacy_policy() {
  var lb = $('#ygm-embedded-indemnity-and-release-lightbox .ygm-titled-text-lightbox').clone(true);
  if (!lb.size()) return;
  plb__lightbox.open(lb);
}

jQuery(document).ready(function($) {
  
  /******************************/
  /* Lightbox'd Terms & Privacy */
  /******************************/

  // simply locate the terms and privacy openers and attach
  // behavior to the properly styled links to open their content
  $('.ygm-terms-of-use-lightbox-opener').click(function(e) {
    e.preventDefault();
    ygm__lb_terms_of_use();
  });
  $('.ygm-privacy-policy-lightbox-opener').click(function(e) {
    e.preventDefault();
    ygm__lb_privacy_policy();
  });  
  $('.ygm-indemnity-and-release-lightbox-opener').click(function(e) {
    e.preventDefault();
    ygm__lb_indemnity_and_privacy_policy();
  });  
  
  /**********************/
  /* News Page (Shared) */
  /**********************/
  
  var d = $('div#ygm-content.ygm-page-news');
  if (d.size())
  {
    // enable the older months link to expand and collapse the archive links
    d.find('div.news-archive div.older-months-link a').click(function(e) {
      e.preventDefault();
      var na = $(this).parents('div.news-archive');
      var om = na.find('div.month-links.older');
      if ($(this).parent().hasClass('down')) 
      {
        // we are opening the list of months
        om.slideDown('normal', function() { 
          var na = $(this).parents('div.news-archive');
          var oml = na.find('div.older-months-link');
          oml.removeClass('down').addClass('up');
        });
      }
      else 
      {
        // we are closing the list of months
        om.slideUp('normal', function() { 
          var na = $(this).parents('div.news-archive');
          var oml = na.find('div.older-months-link');
          oml.removeClass('up').addClass('down');
        });
      }
    });
  }
  
  /*******************************************************/
  /* Shopping Cart Features (Used Across Multiple Pages) */
  /*******************************************************/
  
  // embed a simple function to contact the system and retrieve
  // the total quantity of items in the cart useful after additions
  $('body').data('refresh_total_quantity_of_items', function() {
    
    // define a function which will handle
    // both success and failure of our post
    var complete = function(data, status) { 
      if (!(data instanceof Object)) data = new Object();
                
      // for any type of error just dont update page content
      if ((!data.success) || (status != 'success')) return;
      
      // determine from the response if we use items
      var plural = data.total == '1' ? false : true;
      
      // simply update the plural status and
      // the count with the count string given
      var el = $('.ygm-whats-in-your-cart');
      if (plural) el.find('span.plural').show(); else el.find('span.plural').hide();
      if (data.total != 0)
      {
        // adjust the count and link styles
        el.find('span.count').text(data.total);
        el.find('.checkout').removeClass('disabled');
      }
      
      // no items
      // in cart
      else 
      {
        // based on the different site styles adjust the count string here
        el.find('span.count').text($('body').hasClass('shrd') ? '0' : '');
        el.find('.checkout').addClass('disabled');
      }
    };
    
    // compose and execute ajax request
    $.ajax({ url: window.location.href,
             type: 'POST',
             cache: false,               
             data: { 'gtcms__catalog_store': 'ajax_total_quantity_of_items_in_cart' },
             dataType: 'json',
             success: complete,
             error: function(jqXHR, status, error) { complete(null, status); }});
  });
  
  // this function which we will embed with the body can be
  // called whenever ajax purchasing links need to be powered
  // which might be useful when links are added via ajax
  $('body').data('enable_ajax_buy_links', function() {
    var links = $('body').find('.ygm-ajax-buy');
    links.each(function(i, el) {
      el = $(el);
      if (el.data('ajax-buy-enabled')) return;
      el.click(function(e) {
        e.preventDefault();
        
        // extract the product and quantity from a hidden tag within buy link
        var product_id = parseInt($(this).find('.ygm-product-id').text());
        var quantity = parseInt($(this).find('.ygm-product-qty').text());
        if (!quantity) quantity = parseInt($(this).parent().find('input.ygm-product-qty').val());
        if (!quantity || quantity < 1) quantity = 1;
        
        // show the indicator within a lightbox
        $('body').data('plb__show_activity')();
        
        // define a function which will handle
        // both success and failure of our post
        var complete = function(data, status) { 
          if (!(data instanceof Object)) data = new Object();
          
          // no matter what our response update the page totals
          $('body').data('refresh_total_quantity_of_items')();
                    
          // for any type of error use lightbox error
          // function which has been embedded in the body
          if ((!data.success) || (status != 'success'))
          {
            var error = data.error || 'System/Network error; Please try again.';
            $('body').data('plb__show_error')(error);
          }
          
          // otherwise proceed
          // to open lightbox
          else
          {
            // create a jquery 
            // object from the
            // raw html data
            var lb = $(data.html);
            
            // before opening the lightbox add functionality
            // to the cancel link which makes proper request
            lb.find('.cancel-link').click(function(e) {
              e.preventDefault();
              var td = $(this).parents('td.cancel');
              var just_added_ids = td.find('span.just-added-cart-item-ids').text();
              var just_added_quantities = td.find('span.just-added-cart-item-quantities').text();
              var aja = td.find('div.ajax-activity');
              
              // show the 
              // indicator
              aja.show();
              
              // define a function which will handle
              // both success and failure of our post
              var complete = function(data, status) { 
                if (!(data instanceof Object)) data = new Object();
                
                // for a cancel action we provide no feedback other
                // than updating the total items in cart on the page
                $('body').data('refresh_total_quantity_of_items')();
                plb__lightbox.close();
              };
              
              // compose and execute ajax request
              $.ajax({ url: window.location.href,
                       type: 'POST',
                       cache: false,               
                       data: { 'gtcms__catalog_store': 'ajax_undo_cart_addition',
                               'just_added_cart_item_ids': just_added_ids,
                               'just_added_cart_item_quantities': just_added_quantities
                             },
                       dataType: 'json',
                       success: complete,
                       error: function(jqXHR, status, error) { complete(null, status); }});
            });
          
            // after adding proper behaviors
            // display the lightbox content
            plb__lightbox.open(lb);
          }
        };
        
        // compose and execute ajax request
        $.ajax({ url: window.location.href,
                 type: 'POST',
                 cache: false,               
                 data: { 'gtcms__catalog_store': 'ajax_add_product',
                         'mode': 'single',
                         'product_id': product_id,
                         'quantity': quantity
                       },
                 dataType: 'json',
                 success: complete,
                 error: function(jqXHR, status, error) { complete(null, status); }});
      });
      
      // after enabling the link set flag
      // to prevent us from enabling again
      el.data('ajax-buy-enabled', true);
    });
  });
  
  // enable all purchasing links initially
  $('body').data('enable_ajax_buy_links')();
  
  /***********************************/
  /* Shopping Cart Review & Checkout */
  /***********************************/
  
  var d = $('div#ygm-shopping-cart-review');
  if (d.size())
  {
    // ensure that the disabling
    // screen remain in position
    $(window).resize(function() {
      var od = $('div#ygm-order-details');
      var sc = $('div#ygm-shopping-cart');
      if (od.hasClass('ygm-disabled')) ygm__disabling_screen(od, true);
      if (sc.hasClass('ygm-disabled')) ygm__disabling_screen(sc, true);
    });
    
    // when second step is hidden bring
    // it to visible but faded and disabled
    var od = $('div#ygm-order-details');
    if (od.hasClass('ygm-hidden')) {
      od.addClass('ygm-disabled');
      /* od.css('opacity', 0.48); */
      ygm__disabling_screen(od, true);
      od.show(); 
    }
    
    // disable enter submitting on form
    ygm__disable_enter_submission(od);
    
    // prepare the proper state for link
    // which continues based on the cart
    var sc = $('div#ygm-shopping-cart');
    if (sc.find('p.no-products').size())
      sc.find('div.navigation-links div.right').hide();
    else sc.find('div.navigation-links div.right').show();
    
    /////////// SHOPPING CART ///////////
    
    // declare a resinstallation
    // function at the top here
    var reinstall_table = null;
    
    // establish an update link handler
    // which can be added to table element
    var update_handler = function(e) {
      e.preventDefault();
      e.stopPropagation();
      var sc = $('div#ygm-shopping-cart');
      var tbl = $(this).parents('table.ygm-shopping-cart');
      var td = $(this).parents('td.qty');
      var tr = $(this).parents('tr.item');
      var cart_item_id = parseInt(tr.find('td.number span.cart-item-id').text());
      var qty = parseInt(td.find('input[name=qty]').val());
      var ajs = td.find('img.ajax');
      ajs.show();
      
      // define a function which will handle
      // both success and failure of our post
      var complete = function(data, status) {
        if (!(data instanceof Object)) data = new Object();
        var msg = sc.find('.gtcms-message');
        
        // no matter what our response update the page totals
        $('body').data('refresh_total_quantity_of_items')();
        
        // for any type of error find the message box
        // on the page and insert the proper text there
        if ((!data.success) || (status != 'success'))
        {
          var error = data.error || 'System/Network error; Please try again.';
          msg.addClass('error').removeClass('notice');
          msg.text(error);
        }
        
        // successful removes
        // all message text
        else msg.text('');
          
        // call the function to place
        // the updated table on page
        reinstall_table(data.html);
      };
      
      // compose and execute ajax request
      $.ajax({ url: window.location.href,
               type: 'POST',
               cache: false,               
               data: { 'gtcms__catalog_store': 'ajax_cart_update',
                       'cart_item_id': cart_item_id,
                       'quantity': qty
                     },
               dataType: 'json',
               success: complete,
               error: function(jqXHR, status, error) { complete(null, status); }});
    };
    
    // establish an update link handler
    // which can be added to table element
    var delete_handler = function(e) {
      e.preventDefault();
      e.stopPropagation();
      var sc = $('div#ygm-shopping-cart');
      var tbl = $(this).parents('table.ygm-shopping-cart');
      var td = $(this).parents('td.delete');
      var tr = $(this).parents('tr.item');
      var cart_item_id = parseInt(tr.find('td.number span.cart-item-id').text());
      var ajs = td.find('img.ajax');
      ajs.show();
      
      // define a function which will handle
      // both success and failure of our post
      var complete = function(data, status) {
        if (!(data instanceof Object)) data = new Object();
        var msg = sc.find('.gtcms-message');
        
        // no matter what our response update the page totals
        $('body').data('refresh_total_quantity_of_items')();
        
        // for any type of error find the message box
        // on the page and insert the proper text there
        if ((!data.success) || (status != 'success'))
        {
          var error = data.error || 'System/Network error; Please try again.';
          msg.addClass('error').removeClass('notice');
          msg.text(error);
        }
        
        // successful removes
        // all message text
        else msg.text('');
        
        // call the function to place
        // the updated table on page
        reinstall_table(data.html);
      };
      
      // compose and execute ajax request
      $.ajax({ url: window.location.href,
               type: 'POST',
               cache: false,               
               data: { 'gtcms__catalog_store': 'ajax_cart_delete',
                       'cart_item_id': cart_item_id
                     },
               dataType: 'json',
               success: complete,
               error: function(jqXHR, status, error) { complete(null, status); }});
    };
    
    // encapsulate the process of replacing
    // a new cart table into page with handlers
    var reinstall_table = function(html) {
      var d = $('div#ygm-shopping-cart-review');
      var container = d.find('.cart-table-container');
      container.html(html);
      container.find('td.qty a').click(update_handler);
      container.find('td.delete a').click(delete_handler);
      if (container.find('p.no-products').size())
        d.find('div.navigation-links div.right').hide();
      else d.find('div.navigation-links div.right').show();
    };
    
    // establish the click handlers first time
    var tbl = d.find('table.ygm-shopping-cart');
    tbl.find('td.qty a').click(update_handler);
    tbl.find('td.delete a').click(delete_handler);
    
    /////////// ORDER DETAILS ///////////
    
    // install the functionality to continue from the cart to the first checkout process
    d.find('div#ygm-shopping-cart div.navigation-links a.continue').click(function(e) {
      e.preventDefault();
      e.stopPropagation();
      if (ygm__is_disabled($(this))) return;
      var od = $('div#ygm-order-details');
      var sc = $('div#ygm-shopping-cart');
      var ajs = $(this).parent().find('img.ajax');
      ajs.show();
      
      // define a function which will handle
      // both success and failure of our post
      var complete = function(data, status) {
        if (!(data instanceof Object)) data = new Object();
        var msg = sc.find('.gtcms-message');
        ajs.hide();
        
        // for any type of error find the message box
        // on the page and insert the proper text there
        if ((!data.success) || (status != 'success'))
        {
          var error = data.error || 'System/network error; Please try again.';
          msg.addClass('error').removeClass('notice');
          msg.text(error);
        }
        else
        {
          // remove any other
          // message here
          msg.text('');
          
          // disable shopping cart
          // and enable order details
          /* sc.css('opacity', 0.48); */
          sc.addClass('ygm-disabled');
          ygm__disabling_screen(sc, true);
          /* od.css('opacity', 1.00); */
          od.removeClass('ygm-disabled');
          ygm__disabling_screen(od, false);
          
          // an extra component to the billing details form
          // can be revealed when workshop is on the order
          var iaw = od.find('.ygm-is-attending-workshop');
          if (data.includes_workshop) iaw.show();
          else iaw.hide();
          
          // then replace the supplemental form 
          // html into the proper container on right
          var sd = $('#ygm-supplemental-details');
          sd.html(data.supplemental_forms);
          
          // store the order linkid within the order details
          od.find('input[name=gtcms_order]').val(data.linkid);
          
          // enable disappearing labels
          // on any forms that were added
          // and any other page behaviors
          ygm__enable_behaviors();
          
          // ensure new form elements cannot
          // submit when enter is clicked too
          ygm__disable_enter_submission(od);
          
          // a special arrow graphic will be displayed and flashed when this step is reached
          var times = parseInt(od.find('.ygm-shopping-alert-arrow-number-of-pulsations').text());
          var duration = parseFloat(od.find('.ygm-shopping-alert-arrow-duration-of-pulsation').text());
          od.find('.ygm-shopping-alert-arrow').show().effect('pulsate', { times: times }, (duration*1000));
        }
      };
      
      // compose and execute ajax request
      $.ajax({ url: window.location.href,
               type: 'POST',
               cache: false,               
               data: { 'gtcms__catalog_store': 'ajax_checkout_begin',
                       'originating_site': ($('body').hasClass('shrd') ? 'SHRD' : 'TDW') },
               dataType: 'json',
               success: complete,
               error: function(jqXHR, status, error) { complete(null, status); }});
    });
    
    // install the functionality to go back from the order details to the shopping cart
    d.find('div#ygm-order-details div.navigation-links a.back-to-cart').click(function(e) {
      e.preventDefault();
      e.stopPropagation();
      var od = $('div#ygm-order-details');
      var sc = $('div#ygm-shopping-cart');
      /* od.css('opacity', 0.48); */
      od.addClass('ygm-disabled');
      ygm__disabling_screen(od, true);
      /* sc.css('opacity', 1.00); */
      sc.removeClass('ygm-disabled');
      ygm__disabling_screen(sc, false);
      
      // possibly scroll the window to the top of cart
      /* $('html').animate({ scrollTop: 0 }, 2000); */
      
      // hide the alert arrow until we continue
      od.find('.ygm-shopping-alert-arrow').hide();
    });
    
    // install the functionality to continue from the order details and finish checkout
    d.find('div#ygm-order-details div.navigation-links a.continue').click(function(e) {
      e.preventDefault();
      e.stopPropagation();
      if (ygm__is_disabled($(this))) return;
      var od = $('div#ygm-order-details');
      var sc = $('div#ygm-shopping-cart');
      var co = $('div#ygm-checkout');
      var ajs = $(this).parent().find('img.ajax');
      ajs.show();
      
      // define a function which will handle
      // both success and failure of our post
      var complete = function(data, status) {
        if (!(data instanceof Object)) data = new Object();
        var msg = od.find('.gtcms-message');
        ajs.hide();
        
        // for any type of error find the message box
        // on the page and insert the proper text there
        if ((!data.success) || (status != 'success'))
        {
          var error = data.error || 'System/network error; Please try again.';
          msg.addClass('error').removeClass('notice');
          msg.text(error);
        }
        else
        {
          // remove any other
          // message here
          msg.text('');
         
          // hide the shopping
          // cart and order details
          // and show final page
          sc.hide();
          od.hide();
          co.find('div#ygm-order-review-center .gtcms-message').text('');
          co.show();
          
          // the order number and linkid are provided separately for insertion so put them in their proper place
          co.find('div#ygm-order-review-center div.top div.order-number span.number').text(data.order_number);
          co.find('div#ygm-order-review-center div.top span.linkid').text(data.linkid);
          co.find('div#ygm-order-review-center div.top div.print-link a.print-this').attr('href', 'print_your_order.php?gtcms_order='+data.linkid);
          
          // now replace the compose html which was sent from our server
          co.find('div#ygm-order-review-left').html(data.order_details);
          co.find('div#ygm-order-review-table').html(data.order_table);
          
          // locate the button and adjust the styles to show warning as needed
          var btn = co.find('div#ygm-order-review-center a.checkout-button');
          if (data.requires_registration) btn.removeClass('checkout').addClass('checkout-alert-opener');
          
          // install the functionality to show the checkout alert
          // window as needed when clicked after adjusting styles
          co.find('.checkout-alert-opener').click(function(e) {
            e.preventDefault();
            e.stopPropagation();
            if (ygm__is_disabled($(this))) return;
            var popup = $(this).parents('div.navigation-links').find('div.checkout-alert');
            popup.fadeIn(100);
          });
        }
      };
      
      // begin preparing our
      // post data for order
      var post = new Object();
      post.gtcms__catalog_store = 'ajax_checkout_details'; 
      
      // simply traverse all form fields and post them
      var fields = od.find('input, textarea, select');
      fields.each(function(i, el) { 
        post[$(el).attr('name')] = ygm__real_val($(el));
      });
      
      // compose and execute ajax request
      $.ajax({ url: window.location.href,
               type: 'POST',
               cache: false,               
               data: post,
               dataType: 'json',
               success: complete,
               error: function(jqXHR, status, error) { complete(null, status); }});
    });
    
    // install the functionality to go back from the checkout page to order details
    $('div#ygm-checkout div.navigation-links a.back-to-order').click(function(e) {
      e.preventDefault();
      e.stopPropagation();
      var od = $('div#ygm-order-details');
      var sc = $('div#ygm-shopping-cart');
      var co = $('div#ygm-checkout');
      co.hide();
      sc.show();
      od.show();
      
      // possibly scroll the window to the top of cart
      /* $('html').animate({ scrollTop: 0 }, 2000); */
    });
    
    // install the functionality to dynamically compose and sumbit to paypal
    $('div#ygm-checkout div.navigation-links a.checkout').click(function(e) {
      e.preventDefault();
      e.stopPropagation();
      if (ygm__is_disabled($(this))) return;
      if (!$(this).hasClass('checkout')) return;
      var co = $('div#ygm-checkout');
      var ajs = $(this).parent().find('img.ajax');
      ajs.show();
      
      // define a function which will handle
      // both success and failure of our post
      var complete = function(data, status) {
        if (!(data instanceof Object)) data = new Object();
        var msg = co.find('.gtcms-message');
        
        // for any type of error find the message box
        // on the page and insert the proper text there
        if ((!data.success) || (status != 'success'))
        {
          var error = data.error || 'System/network error; Please try again.';
          msg.addClass('error').removeClass('notice');
          msg.text(error);
          ajs.hide();
        }
        else
        {
          // remove any other
          // message here
          msg.text('');
         
          // the response includes the internals
          // of paypal form so insert and submit
          var pf = $('form#ygm-paypal-form');
          pf.html(data.paypal);
          pf.get(0).submit();
        }
      };
      
      // compose and execute ajax request
      $.ajax({ url: window.location.href,
               type: 'POST',
               cache: false,               
               data: { 'gtcms__catalog_store': 'ajax_checkout',
                       'gtcms_order': co.find('div#ygm-order-review-center div.top span.linkid').text()
                     },
               dataType: 'json',
               success: complete,
               error: function(jqXHR, status, error) { complete(null, status); }});
    });
    
    // we are going to enable the paypal imagery to function the same as checkout link
    $('div#ygm-checkout div.paypal-overview a.paypal-accepts').click(function(e) {
      e.preventDefault();
      e.stopPropagation();
      $('div#ygm-checkout div.navigation-links a.checkout.text-link').trigger('click');
    });
  }
  
  /***********************/
  /* Ticket Registration */
  /***********************/
  
  var d = $('div#ygm-content.ygm-page-ticket-registration');
  if (d.size())
  {
    // obtain references to the possible right column content elements
    // then place a disabling screen when we are showing registration
    // allowing the continue button to release the screen when ready
    var rt = d.find('.ygm-standard-right-column div.registered-to');
    var mpf = d.find('.ygm-standard-right-column div.ygm-multipane-form');
    if (rt.hasClass('ygm-hidden'))
    {
      // fade it and show it
      // although it is disabled
      /* mpf.css('opacity', 0.48); */
      ygm__disabling_screen(mpf, true);
      mpf.show();
    }
    var cb = d.find('.ygm-standard-left-column a.continue').click(function(e) {
      var d = $(this).parents('div#ygm-content.ygm-page-ticket-registration');
      var mpf = d.find('.ygm-standard-right-column div.ygm-multipane-form');
      /* mpf.css('opacity', 1.0); */
      ygm__disabling_screen(mpf, false);
    });
    
    // attach the proper behaviors to the navigation buttons of the form
    mpf.find('.ygm-multipane-navigation a.forward').click(function(e) {
      e.preventDefault();
      var mpf = $(this).parents('div.ygm-multipane-form');
      var mpn = $(this).parents('div.ygm-multipane-navigation');
      var aja = $(this).parent().find('img.ajax');
      
      // determine which form to submit based
      // on the step indicated by conatiner 
      if (mpf.hasClass('ygm-showing-index-1'))
        var f = mpf.find('.ygm-form-pane.ygm-index-1 form');
      if (mpf.hasClass('ygm-showing-index-2'))
        var f = mpf.find('.ygm-form-pane.ygm-index-2 form');
      if (mpf.hasClass('ygm-showing-index-3'))
        var f = mpf.find('.ygm-form-pane.ygm-index-3 form');
      if (mpf.hasClass('ygm-showing-index-4'))
        var f = mpf.find('.ygm-form-pane.ygm-index-4 form');
      
      // dynamically build the
      // array of form fields
      var post = new Object();
      var fields = f.find('input[type=text], input[type=hidden], textarea, select');
      fields.each(function(j, el) {
        var el = $(el);
        post[el.attr('name')] = ygm__real_val(el);
      });
      
      // show activity
      // indicator
      aja.show();
      mpn.find('.gtcms-message').text('');
      
      // define a function which will handle
      // both success and failure of our post
      var complete = function(data, status) {
        if (!(data instanceof Object)) data = new Object();
        var msg = mpn.find('.gtcms-message');
        aja.hide();
        
        // for any type of error find the message box
        // on the page and insert the proper text there
        if ((!data.success) || (status != 'success'))
        {
          var error = data.error || 'System/network error; Please try again.';
          msg.addClass('error').removeClass('notice');
          msg.text(error);
        }
        else
        {
          // remove any other
          // message here
          msg.text('');
          
          // determine which
          // pane to show
          var pane = 1;
          if (data.step == 1) pane = 2;
          if (data.step == 2) pane = 3;
          if (data.step == 3) pane = 4;
          if (data.step == 4)
          {
            // we can reload to show complete details
            mpf.find('form.ygm-refresh').get(0).submit();
            return;
          }
          
          // hide all panes before showing
          mpf.find('.ygm-form-pane').hide();
          for (var i=1; i<=4; i++) mpf.removeClass('ygm-showing-index-'+i);
          
          // in all cases when we have moved forward we can now move backward as well
          mpn.find('a.back img.ygm-form-step-backward').removeClass('ygm-disabled');
          
          // show the pane and adjust container styles
          mpf.find('.ygm-form-pane.ygm-index-'+pane).show();
          mpf.addClass('ygm-showing-index-'+pane);
        }
      };
      
      // compose execute ajax request
      $.ajax({ url: 'register.php',
               type: 'POST',
               cache: false,               
               data: post,
               dataType: 'json',
               success: complete,
               error: function(jqXHR, status, error) { complete(null, status); }});
    });
    
    
    // attach the proper behaviors to the navigation buttons of form
    mpf.find('.ygm-multipane-navigation a.back').click(function(e) {
      e.preventDefault();
      var mpf = $(this).parents('div.ygm-multipane-form');
      var mpn = $(this).parents('div.ygm-multipane-navigation');
      
      // initialize 
      // destination
      var pane = 1;
      
      // hide all panes before showing
      mpf.find('.ygm-form-pane').hide();
      for (var i=1; i<=4; i++)
      {
        // note which pane is our current page and unstyle
        if (mpf.hasClass('ygm-showing-index-'+i)) pane = i-1;
        mpf.removeClass('ygm-showing-index-'+i);
      }
      
      // validate the index
      if (pane < 1) pane = 1;
      
      // show the pane and adjust container styles
      mpf.find('.ygm-form-pane.ygm-index-'+pane).show();
      mpf.addClass('ygm-showing-index-'+pane);
      
      // when we reach the first pane be sure to add the styles to disable backward navigation
      if (pane == 1) mpn.find('a.back img.ygm-form-step-backward').addClass('ygm-disabled');
    });
  }
  
});

jQuery(window).load(function() {
  var $ = jQuery;

  /***************************/
  /* Google-Powered Walk Map */
  /***************************/
  
  var d = $('div#ygm-google-walk-map');
  if (d.size())
  {
    // we must have available the embedded map parameters
    // describing some of the behaviors of the map used
    var p = $('div#ygm-google-walk-map-parameters');
    if (!p.size()) return;
    
    // prepare the map based on the parameters configured and extracted from the page then store map object with the page element
    var latlng = new google.maps.LatLng(parseFloat(p.find('.map-center-lat').text()), parseFloat(p.find('.map-center-lng').text()));
    var options = {
      zoom: parseInt(p.find('.zoom-level').text()),
      center: latlng,
      mapTypeId: google.maps.MapTypeId.TERRAIN,
      mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR },
      navigationControlOptions: { style: google.maps.NavigationControlStyle.ZOOM_PAN },
      scaleControl: true 
    };
    
    // create the map object associating it with the proper
    // element and ensure we are successful in our creation
    d.data('map', new google.maps.Map(d.get(0), options));
    if (!d.data('map')) return;
    
    // create the proper overlay object for the route itself which is placed on top of map
    // in the form of an image whose bounding rectangle is embedded in the form of coordinates
    var bounds = new google.maps.LatLngBounds(new google.maps.LatLng(parseFloat(p.find('.route-sw-lat').text()), parseFloat(p.find('.route-sw-lng').text())), 
                                              new google.maps.LatLng(parseFloat(p.find('.route-ne-lat').text()), parseFloat(p.find('.route-ne-lng').text())));
    d.data('map_walk_route', new google.maps.GroundOverlay(p.find('.route-url').text(), bounds));
    /* d.data('map_walk_route').setMap(d.data('map')); */
    
    // associate the marker images
    // with the map for easy access
    var marker_images = new Object();
    d.data('marker_images', marker_images);
    
    // establish the marker images used with
    // their dimensions and achoring points
    marker_images['we_recommend'] = new google.maps.MarkerImage(
      'pics/itm__google_map_star.png',
      new google.maps.Size(26, 25),
      new google.maps.Point(0,0), // origin
      new google.maps.Point(11, 10) // anchor
    );
    marker_images['points_of_interest_major'] = new google.maps.MarkerImage(
      'pics/itm__google_map_dot_major.png',
      new google.maps.Size(26, 26),
      new google.maps.Point(0,0), // origin
      new google.maps.Point(13, 11) // anchor
    );
    marker_images['points_of_interest_minor'] = new google.maps.MarkerImage(
      'pics/itm__google_map_dot_minor.png',
      new google.maps.Size(17, 17),
      new google.maps.Point(0,0), // origin
      new google.maps.Point(8, 7) // anchor
    );
    marker_images['participant_hometowns'] = new google.maps.MarkerImage(
      'pics/itm__google_map_blue_balloon.png',
      new google.maps.Size(30, 42),
      new google.maps.Point(0,0), // origin
      new google.maps.Point(14, 41) // anchor
    );
    
    // associate the dimensions of infowindows
    // with the map for easy access and config
    marker_infowindow_maxwidths = new Object();
    d.data('marker_infowindow_maxwidths', marker_images);
    marker_infowindow_maxwidths['we_recommend'] = 300;
    marker_infowindow_maxwidths['points_of_interest_major'] = 200;
    marker_infowindow_maxwidths['points_of_interest_minor'] = 200;
    marker_infowindow_maxwidths['participant_hometowns'] = 200;
    
    // establish associative
    // arrays to hold references
    // to all markers on map
    var markers = new Object;
    d.data('markers', markers);
    var markers_by_type = new Object;
    d.data('markers_by_type', markers_by_type);

    // each marker on the
    // map will be identified
    // by its z-index so use
    // this variable to ensure
    // no two indexes are same
    var index = 0;
    
    // loop across all the possible marker types in order to construct the map with all types of markers as the method is similar
    var marker_types = new Array('points_of_interest_major', 'points_of_interest_minor', 'participant_hometowns', 'we_recommend');
    for (var marker_types_index=0; marker_types_index<marker_types.length; marker_types_index++)
    {
      // establish an object as an
      // associative array which will
      // hold all the markers of the
      // type we are now processing
      // as lookup by type and by 
      // index are both necessary
      var marker_set = new Object;
      markers_by_type[marker_types[marker_types_index]] = marker_set;
      
      // the specifications for all the map markers are embedded on the page from the content management
      // system so find the properly classed elements and build a memory array of all the marker objects
      var els = $('#ygm-google-walk-map-markers').find('.markers.'+marker_types[marker_types_index]+' .marker');
      els.each(function(i, el) {
        el = $(el);
        var lat = el.find('.lat').text();
        var lng = el.find('.lng').text();
        var title = el.find('.title').text();
        var description = el.find('.description').text();
        
        // create a wrapper object
        // for the actual map marker
        // and store in both our
        // organizational arrays
        var marker = new Object;
        markers['index_'+index] = marker;
        marker_set['index_'+index] = marker;
        
        // use the api to create the actual 
        // map marker object using the z-index
        // property to uniquely identify marker
        marker.obj = new google.maps.Marker({ 
          position: new google.maps.LatLng(lat, lng), 
          map: d.data('map'),           
          icon: marker_images[marker_types[marker_types_index]],
          zIndex: index
        });
        
        // obtain a short reference to the proper anchor on the marker image
        var anchor = marker_images[marker_types[marker_types_index]].anchor;
        
        // only when extra information is 
        // available add the info window 
        if (title != '' || description != '')
        {
          // associate the proper info window with the marker by storing it in the wrapper object which is itself stored in properly keyed arrays
          marker.infowindow = new google.maps.InfoWindow({ content: '<div class="ygm-google-map-infowindow '+marker_types[marker_types_index]+'"><h3>'+title+'</h3>'+description+'</div>', maxWidth: marker_infowindow_maxwidths[marker_types[marker_types_index]], pixelOffset: new google.maps.Size(0, anchor.y+1)});
          
          // enable click action on a marker to open its associated info
          // and enable hovering to open and close unless opened with click
          google.maps.event.addListener(marker.obj, 'click', function() {
            var d = $('div#ygm-google-walk-map');
            var marker = d.data('markers')['index_'+this.getZIndex()];
            if (!(marker.infowindow._hard_opened || marker.infowindow._soft_opened))
              marker.infowindow.open(d.data('map'), this);
            marker.infowindow._hard_opened = true;
            google.maps.event.addListener(marker.infowindow, 'closeclick', function() {
              this._hard_opened = false;
              this._soft_opened = false;
              return true;
            });
          });
          google.maps.event.addListener(marker.obj, 'mouseover', function() {
            var d = $('div#ygm-google-walk-map');
            var marker = d.data('markers')['index_'+this.getZIndex()];
            if (marker.infowindow._hard_opened) return;
            marker.infowindow._soft_opened = true;
            marker.infowindow.open(d.data('map'), this);
          });
          google.maps.event.addListener(marker.obj, 'mouseout', function() {
            var d = $('div#ygm-google-walk-map');
            var marker = d.data('markers')['index_'+this.getZIndex()]
            if (marker.infowindow._hard_opened) return;
            marker.infowindow.close();
          });
        }
        
        // prepare to uniquely
        // index next marker
        index++;
      });
    }
    
    /**************/
    /* Map Routes */
    /**************/
    
    // establish associative
    // arrays to hold references
    // to all routes on map
    var routes = new Object;
    d.data('routes', routes);
    
    // locate the route specification within designated element
    var els = $('#ygm-google-walk-map-routes').find('.route');
    els.each(function(i, el) {
      el = $(el);
      var id = el.find('.id').text();
      var color = el.find('.color').text();
      var weight = parseFloat(el.find('.stroke-weight').text());
      var opacity = parseFloat(el.find('.stroke-opacity').text());
      
      // locate the points within the
      // route specification skipping
      // when no points can be found
      var points = el.find('.point');
      if (!points.size()) return;
      var coords = new Array();
      points.each(function(i, pt) {
        pt = $(pt);
        coords[coords.length] = new google.maps.LatLng(parseFloat(pt.find('.lat').text()), parseFloat(pt.find('.lng').text()));
      });
      
      // create the line object with parameters
      var route = new google.maps.Polyline({
        path: coords,
        strokeColor: color,
        strokeOpacity: opacity,
        strokeWeight: weight
      });
      
      // place the route on the map
      route.setMap(d.data('map'));
      
      // retain a reference to 
      // the route in global array
      routes['route'+id] = route;
    });
    
    // when controls on the map are present allow them
    // to show and hide the designated sets of markers
    var controls = $('div#ygm-google-walk-map-controls');
    if (controls.size())
    {
      // enable all toggling elements to open and close
      // the legend when they are clicked based on state
      controls.find('.legend-toggler').click(function(e) {
        var c = $('div#ygm-google-walk-map-controls');
        var lgn = c.find('div.legend');
        if (c.hasClass('legend-open')) lgn.slideUp('normal', 'swing', function() {
          var c = $('div#ygm-google-walk-map-controls');
          c.removeClass('legend-open');
        });
        else lgn.slideDown('normal', 'swing', function() {
          var c = $('div#ygm-google-walk-map-controls');
          c.addClass('legend-open');
        });
      });
      
      // based on the marker toggling link 
      // click show and hide the marker set
      controls.find('.overlay-toggler').click(function(e) {
        e.preventDefault();
        var d = $('div#ygm-google-walk-map');
        var map = d.data('map');
        var markers_by_type = d.data('markers_by_type');
        var t = $(this);
        
        // in all cases we will
        // toggle so do this
        t.toggleClass('off');
        var on = !t.hasClass('off');
        
        // for both types of interesting points
        if (t.hasClass('points-of-interest'))
        {
          // simply retrieve the set of markers and loop across to either
          // hide or show the map marker based on the state of the toggler
          var marker_set = markers_by_type['points_of_interest_major'];
          if (marker_set instanceof Object) for (id in marker_set)
            if (on) marker_set[id].obj.setMap(map); else marker_set[id].obj.setMap(null);
          var marker_set = markers_by_type['points_of_interest_minor'];
          if (marker_set instanceof Object) for (id in marker_set)
            if (on) marker_set[id].obj.setMap(map); else marker_set[id].obj.setMap(null);
        }
        
        // for the blue balloons of participants
        if (t.hasClass('participant-hometowns'))
        {
          // simply retrieve the set of markers and loop across to either
          // hide or show the map marker based on the state of the toggler
          var marker_set = markers_by_type['participant_hometowns'];
          if (marker_set instanceof Object) for (id in marker_set)
            if (on) marker_set[id].obj.setMap(map); else marker_set[id].obj.setMap(null);
        }
        
        // for the recommended stars
        if (t.hasClass('we-recommend'))
        {
          // simply retrieve the set of markers and loop across to either
          // hide or show the map marker based on the state of the toggler
          var marker_set = markers_by_type['we_recommend'];
          if (marker_set instanceof Object) for (id in marker_set)
            if (on) marker_set[id].obj.setMap(map); else marker_set[id].obj.setMap(null);
        }
        
        // for routes with identifiers
        if (t.hasClass('custom-route'))
        {
          // the identifier for the custom route is embedded so extract
          // then locate the route in the global array and toggle visible
          var id = parseInt(t.parents('.overlay').find('.id').text());
          if (!id) return;
          var route = routes['route'+id];
          if (on) route.setMap(map); else route.setMap(null);
        }        
      });
    }
  }
  
  /*****************/
  /* Shopping Cart */
  /*****************/
  
  // in order to ensure the 
  // that the disabling screen
  // is properly sized trigger
  // a resize event to update
  $(window).resize();
});


