TA.UTIL = {

    upper:function(word)
    {
        return word.substr(0,1).toUpperCase() + word.substr(1);
    },
    lower:function(word)
    {
      return word.toLowerCase();
    },

    accordion: function()
    {
         $('#calltoaction .c2c').bind('click',function()
        {   
            $('#clickToCallHolder').slideToggle();
        });
    },
    
    superFishMainMenu: function()
    {
          $(function()
          {
              $('#navmenu-h').superfish();
          });
    },

    format: function(string)
    {
        var args = arguments;
        var pattern = new RegExp('{([1-' + arguments.length + '])}','g');
        return String(string).replace(pattern, function(match, index) { return args[index]; });
    },

/**

     * Check all products on the page for 0 pricing and format departure dates
     *
     * ###Process:
     *
     * * Find un-priced product and remove 'from'
     * * Format departure dates as they come out of ProCat ugly
     * * Truncate product description as they are huge
     * * Truncate package description for landing page product display
     * * Truncate package description for search result style product display
     */

    productContentCheck: function()
    {

        var $content = $('#panel');

        // Find un-priced product and remove 'from'
        $content.find('div.price:contains("Call")').each(function()
        {
            $(this).html(function(i, html)
            {
                return html.replace(/from/, '');
            });
        });

        // Format departure dates as they come out of ProCat ugly
         $content.find('.departureDate').each(function()
         {

            $(this).html(function(i, html)
            {

                if(html.indexOf('no-travel-dates') > -1)
                {
                    return 'Unavailable';
                }

                // If return html un-modified if no dates in expected format are found
                var dates = html.match(/[0-9]{4}(\/|\-)[0-9]{2}(\-|\/)[0-9]{2}/gm);
                var dateSplit = '';
                               
                if(dates === null)
                {
                    return html;
                }

                var dateString = '';

                $.each(dates, function(i)
                {
                    dateSplit = dates[i].match(/(\-|\/)/gm);

                    var d = dates[i].split(dateSplit[i]);
                    var date = FCL.DATETIME.stringToDate([d[2], d[1], d[0]].join('/'));
                    dateString += date.fclFormat('d M Y') + ', ';
                });
                dateString = dateString.substring(0, 13);
                $(this).show();
                return dateString.substring(0, dateString.length - 2);
            });
         });

        // Truncate package description for landing page product display
        $content.find('div.pStyle1 .overview').fclTruncateText({ maxLength: 50 });

    },

    /**
     * Checks all ship images found on the page if they're valid using CANZ.UTIL.isBrokenImage().  If broken, they are replaced with the cruise factory image for the ship.
     */
    checkBrokenShipImages: function()
    {
        var _this = this;

        $('#contentColumn img.ship').each(function()
        {
            if(_this.isBrokenImage($(this)))
            {
                var $image = $(this);
                var cruiseLineShipParts = $(this).attr('src').match(/\/cruise\-lines\/([a-z0-9\-]+)\/cruise\-ships\/([a-z0-9\-]+)/);
                if(cruiseLineShipParts!=null) {
                    _this.getShipInfo(cruiseLineShipParts[1], cruiseLineShipParts[2], function(ship)
                    {
                        $image.attr('src', ship.cruiseFactoryImage);
                    });
                }
            }
        });
    },

    /**
     * Checks all cruise product images, if itinerary image is broken use ship image, if ship image is broken use supplier image, if supplier image is broken use default image
     */
    checkBrokenCruiseImages: function() 
    {

        FCL.SIGNALS.listen('TA.CRUISE_SEARCH_RESULTS', 'reloadProductImages', function()
        {
          $('img.productImage').each(function() {
            $(this).attr('src',$(this).attr('src'));
          });
        });

        $('img.productImage').bind('error',function() {

            var cruiseLine = $(this).attr('data-cruise-line').toLowerCase().replace(/ /g, '-'),
                cruiseShip = $(this).attr('data-cruise-ship').toLowerCase().replace(/ /g, '-');

            //p&o-cruises needs to be changed to po-cruises
            cruiseLine = cruiseLine.replace(/&/g, '');

            if($(this).attr('src') == '/cms_images/cruise-lines/'+cruiseLine+'/cruise-ships/'+cruiseShip+'/'+cruiseShip+'.jpg') 
            {
              $(this).attr('src','/cms_images/cruise-lines/'+cruiseLine+'/logo.jpg');
              return;
            } 
            else if($(this).attr('src') == '/cms_images/cruise-lines/'+cruiseLine+'/logo.jpg') 
            {
              $(this).attr('src','/cms_images/product-images/default-images/generic-default.png');
              return;
            } 
            else 
            {
              $(this).attr('src','/cms_images/cruise-lines/'+cruiseLine+'/cruise-ships/'+cruiseShip+'/'+cruiseShip+'.jpg');
            };

          });

          FCL.SIGNALS.send('TA.CRUISE_SEARCH_RESULTS', 'reloadProductImages');
    },

    /**
     * Replaces broken product images with CANZ.SETTINGS.defaultProductImagePath
     */
    checkBrokenProductImages: function()
    {
        $('body').find('img.productImage').each(function()
        {
            if($(this).fclIsImageBroken() == true)
            {
                $(this).attr('src', CANZ.SETTINGS.defaultProductImagePath);
            }
        });
    },

    showEmergencyMessage: function(){
        $(function(){
            var msgLength = ($('.emergencyMessage').html().length);
            if(msgLength>20){
               $($('#emergencyMessageHolder').html()).insertBefore($('#headerimg'));
            }
        });
    },

    openTabFromUrlVar: function(){
        var tabIndex = FCL.UTIL.getUrlVar('tabIndex');
        $('#tabs').fclTabs('showTab',tabIndex);
    },

    activateExpander: function($elements)
    {
        var $elements = $elements || $('.jqueryExpander');
        $elements.each(function()
        {
            var slicePoint = $(this).data('expander') || 350;
            $(this).expander({ slicePoint: slicePoint });
        });
    },

     /**
     * Makes an element appear after a certain amount of time and remove the onLoad handler related to it.
     * @param {Object} $el The element to appear after a set time
     * @param {Object} $loader The onLoad handler to be removed
     * @param {Number} delay Time until the element appears
     */

    displayOnLoad: function($el, $loader, delay)
    {
        setTimeout(function()
        {
            $el.removeClass('hide').show();
            $loader.remove();
        }, delay);
    },

    paginateTable: function($table, num, buttonText){

      var _this = this;
      if($table.find('tr').length <= 10){return};
      $table.find('tr:lt('+num+')').attr('class', 'show');
      $table.find('tr:gt('+num+')').attr('class', 'hidden').hide();

      $table.after('<div id="moreButton" class="readMoreActionContainer"><a class="readMore">'+buttonText+'</a></div>');

      $('#moreButton').bind('click', function(){
        var currentNumber = $table.find('tr.show').length,
        numberToShow = currentNumber + num;
        $('.itineraries tr:lt('+numberToShow+')').attr('class','show').fadeIn('slow');
        if($table.find('tr.hidden').length == 0){
          $('#moreButton').remove();
        }

      });
    },

    setupBreadcrumbMenu: function(breadcrumbWidths){

        // Set up hovers for #breadcrumbMenu1
        $(function(){$('#breadcrumbMenu1').superfish({autoArrows:false})});

        // Grab the url, the site structure and file names must reflect the original ul items
        var pathname = window.location.pathname.split('/');

        // Grab each url item starting at number 2 since this is where our destinational structure begins (note: updated to reflect removal of /inspiration/ with rewrite)
        $.each(pathname, function(i, value){
            if(i < 2){return;};

            // Change url string to have title caps, replace and with &amp; and hardcode the ones that don't fit
            dest = FCL.UTIL.titleCaps(pathname[i]).replace(/\-/g, ' ');
            dest = dest.replace(/\ and /g, ' &amp; ');
            if(dest == 'Europe &amp; Uk'){dest = 'Europe &amp; UK'}
            if(dest == 'Usa'){dest = 'USA'}

            // In #breadcrumbMenu1 find the ul li that matches url string and create a new ul element with those li items
            var $newMenu = $('#breadcrumbMenu1 a:match("/^'+dest+'$/")').parent().clone();

            // Attach the new menu inside the breadcrumb container, wrap it in a ul and apply custom id
            $('#breadcrumbContainer').find(".sf-shadow:last").after($newMenu);
            $newMenu.wrap('<ul id="breadcrumbMenu'+(i)+'" style="display:inline-block;" />');

            // If the new menu has sub menus apply the down arrow icon
            if($('#breadcrumbMenu'+(i)+' li').length > 1){
              $('#breadcrumbMenu'+(i)+' a:match("/^'+dest+'$/")').append('<div class="downArrow" style="*position:relative; *top:-25px;"></div>')
            }

            // Set up hovers for the new menu
            $(function(){$('#breadcrumbMenu'+(i)+'').superfish({autoArrows:false})});
            
            i++;
        })
  },
  parseProductProperties: function()
  {
    var _this = this;
    var productProperties = Array();

    $('meta[name^="product."]').each(function()
    {
      var key = $(this).attr('name').match(/\.(.*)$/)[1];
      var value = $(this).attr('content');
      productProperties[key] = value;
    });
    
    return productProperties;
  },
  getSku: function()
  {
    try
    {
      var url = window.location.pathname;
      var sku = url.substring( url.lastIndexOf('-') ).match(/\d+/);
      if(sku == null)
      {
        return 'null';
      }
        return sku[0];
      }
        catch(e)
      {
        return 'null';
  }
  }
};

/**
 * FCL Library Overrides Needed Engine parameter from core1.1
 */

/**
 * Helper for getting results of product queries via AJAX
 * @param {String} query
 * @param {Sring} template
 * @param {Function} [callback=function(){}]
 * @param {String} type Default is html, other supported type is "json"
 * @param {Object} [context=Window] The context the callback will be called in. Default is window.
 * @param {String} [engine=stringtemplate] While current default is "stringtemplate", specify "freemarker" to use Freemarker templates
 */

FCL.UTIL.ajaxQuery = function(query, template, callback, type, context, engine)
{
    var context = context || window;
    var type = type || 'html';
    var engine = engine || 'stringtemplate';
    var query = '<securequery template="{1}" consumer="CruiseFactoryAu" engine="{2}">{3}</securequery>'.fclFormat(template, engine, query);

    $.post('/ajax/sitecat', { content: query }, function(data)
    {
        if(type == 'json')
        {
            data = (new Function('return ' + data))();
        }

        callback.call(context, data);
    }, 'html');

};
