/*é*/
/**
 *
 * @package     karzoo
 *
 * @author      Dieter Raber <me@dieterraber.net>
 * @copyright   Dieter Raber 22.08.2007 22:05:07
 *
 * $Id: main.js 230 2009-09-29 07:19:55Z kosny $
 */
//social bookmarking with addthis
addthis_pub             = 'karzoo';
addthis_logo            = 'http://www.karzoo.eu/media/fr/logo-rss.png';
//specify the icon here instead of the text
addthis_brand           = '<img class="addthis-logo" src="/media/karzoo-k.png" />';
addthis_options         = 'favorites, digg, delicious, technorati, reddit, stumbleupon, myspace, facebook, google, more';
addthis_caption_share   = __('bookmark_and_share');
addthis_caption_email   = __('mail_a_friend');
addthis_css             = '/css/addthis.css';


// code yanked from the Yahoo media player
if (! ("console" in window) || !("firebug" in console)) {
  var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
  window.console = {};
  var namesLength = names.length;
  while(namesLength--) {
    window.console[namesLength] = function() {};
  }
}


// global vars, used everywhere
var mediaPath    = null;
var VIRTUAL_ROOT = '';

//calendar object
var cal;

var rh;

var ajaxUrl = '';


jQuery.noConflict();
jQuery(function(jQuery) {

  jQuery('.popup').hide();

  if( jQuery('.js-popup-link') && jQuery('.js-popup-link').length > 0 ) {
    jQuery('.js-popup-link').overlay( {
        expose: {
          color: '#ffffff' ,
          loadSpeed: 20 ,
          opacity: 0.50
        } ,
        left: 'center'
      }
    );
  }


  mediaPath   = getMediaPath();
  
  ajaxUrl     = mediaPath.replace(/\/media/, '/actions');

  VIRTUAL_ROOT = mediaPath.replace(/\/media/, '');

  // modify global settings for tooltips
  jQuery.extend(jQuery.fn.Tooltip.defaults, {
          track: true,
          delay: 0,
          fixPNG:true
  });

  //general ajax setup, this way the other ajax requests do not need to specify this
  jQuery.ajaxSetup({
    url: ajaxUrl,
    timeout: 4000,
    type: 'POST'
  });

  /********************************************     the switch between the different country sites     **************************************/
  jQuery('#switch_to').change(function(){
                        if(this.value) {
                          var currHostData = window.location.host.split('.');
                          if(currHostData.length == 3) {
                            window.location.href = window.location.protocol + '//www.' + currHostData[1] + '.' + this.value + '/' + currentLang + '/';
                          }
                          else{
                            window.location.href = 'http://www.karzoo.' + this.value;
                          }
                        }
                      })
                      .next('button').hide();

  jQuery('#bd-user #event-listing, #my-journeys, #my-fav-journeys, #messages, #tbl-evalreceived, #tbl-evalgiven, #carpool-list').addDetailsOpener();


  //add js action to buttons
  jQuery().addJsEvents();

  /******************************************************* messages part  ******************************************************/
  //the periodical updater for the unread message count
  if(document.getElementById('unreadCountSide')) {
    jQuery.myUpdater.set({delay: 300000, //every 5 minutes
                          callback: updateUnreadCounters,
                          params: {action: 'getUnreadCount',
                                   format: '%1'}});
  }
  
  /*******************  default destination address in search box *********************/
  var searchUseDefault = document.getElementById('SearchUseDefault');
  if(searchUseDefault) {
    
    var disableDestFields = function(isChecked) {
      var disabledState = false;
      var inputBgColor  = '#fff';
      if(isChecked) {
        disabledState = 'disabled';
        inputBgColor  = '#ccc';        
      }
      jQuery('#SearchDestCity').attr('disabled', disabledState).css('backgroundColor', inputBgColor);
      jQuery('#SearchDestStreet').attr('disabled', disabledState).css('backgroundColor', inputBgColor);
    };
    
    //check on load of the page
    disableDestFields(searchUseDefault.checked);
    
    //check on change of the checkbox
    jQuery(searchUseDefault).click(function() {
      disableDestFields(this.checked);
    });
  }
  
  /************** autocomplete of city in search forms ****************/
  if(document.getElementById('SearchDepCity')) {
      
      //autocomplete the city
      jQuery('#SearchDestCity').autocomplete(ajaxUrl, {
        minChars : 2,
        max: 9,
        moreItems: '...',
        extraParams : {
          action: 'acCity',
          country_id: function() { return jQuery("#SearchDestCountryId").val();}
        }
      });
      jQuery("#SearchDestCountryId").change(function() {
        jQuery('#SearchDestCity').flushCache();
      });
      
      jQuery('#SearchDepCity').autocomplete(ajaxUrl, {
        minChars : 2,
        max: 9,
        moreItems: '...',
        extraParams : {
          action: 'acCity',
          country_id: function() { return jQuery("#SearchDepCountryId").val();}
        }
      });   
      jQuery("#SearchDepCountryId").change(function() {
        jQuery('#SearchDepCity').flushCache();
      });
   }



  /*********************** index page **********************************/
  if(document.body.id == 'bd-index') {
    //put the link for register on the entire li
    jQuery('#step1').css('cursor', 'pointer')
                    .click(function(){
                       var jElem = jQuery('a', this);
                       var linkHref   = jElem.attr('href');
                       var linkTarget = jElem.attr('target');
                       if(linkTarget == '_blank') {
                        //there is no really good way to open in blank, so open in top
                        if(self != top) {                         
                          top.location.replace(linkHref);
                        }
                        else {                         
                          window.location.replace(linkHref);                          
                        }
                       }
                       else{                       
                         window.location.replace(linkHref);
                       }
                       return false;
                    });    

  }

  /*********************** the all journeys page **********************************/
  else if(document.body.id == 'bd-journeys' || document.body.id == 'bd-special') {
    addDetailsLink();
  }

  /******************************** le covoiturage  *****************************************/
  else if(document.body.id == 'bd-covoiturage') {

    jQuery('#map-advantages area').Tooltip({extraClass : 'tt-big'}).css('cursor', 'help')
        .click(function() {
      return false;
    });


    jQuery('#questions div').click(function() {
      var target = jQuery('a', this).attr('href');
      if(target) {
        document.location.href = jQuery('a', this).attr('href');
      }
    }).not('.active').css('cursor','pointer');
  }

  /******************************** open and close the faq  *****************************************/
  else if(document.body.id == 'bd-faq') {
    jQuery('dd').hide();
    jQuery('dt').css('cursor', 'pointer')
                       .click(function() {
      var dd = jQuery(this).next();
      if(dd.is(':visible')) {
        dd.hide();
        jQuery(this).removeClass('clicked');
      }
      else{
        jQuery('dd').hide();
        jQuery('dt').removeClass('clicked');
        jQuery(this).addClass('clicked');
        dd.show();
      }
      return false;
    });
    //if we have a certain faq as anchor, open this one to display
    if(window.location.hash) {
      jQuery(window.location.hash).addClass('clicked').next().show();
    }
  }

  /********************************** the link to the details on the entire events page *********************/
  else if(document.body.id == 'bd-events-list') {
    addDetailsLink('event');
  }
  //the details for any journeys listed on a single events page
  else if(document.body.id == 'bd-events-single') {
    addDetailsLink();
  }
  
  /********************************* meteo page *******************************/
  //autosubmit of form for selecting a city
  else if(document.body.id == 'bd-meteo') {
    //autosubmit of select field
    var citySelect = document.getElementById('meteo-city');
    if(citySelect) {
      citySelect.onchange = function() {
        var hrefTarget = window.location.protocol + '//' + window.location.host + '/' + currentLang;
        if(window.location.href.toString().indexOf(currentLang + '/meteo') !== false) {
          hrefTarget = hrefTarget + '/meteo/index';
        }

        if(this.name == 'country') {
          window.location.href = hrefTarget + '/' + this.value;
        }
        else{
          var country = this.form.elements.country.value;
          window.location.href = hrefTarget + '/' + country + '/' + this.value;
        }
        this.form.submit = false;
      };
    }

    //hover effect on country map
    jQuery('area').mouseover(function() {
      var countryId = this.className;
      document.getElementById('country-map').style.backgroundImage = 'url(' + mediaPath + '/meteo/' + countryId + '.png)';
    });

    //keep current country highlighted on mouseout
    jQuery('#country-map').mouseout(function() {
      var oriCountryId = this.className;
      if(oriCountryId) {
        this.style.backgroundImage = 'url(' + mediaPath + '/meteo/' + oriCountryId + '.png)';
      }
      else{
        this.style.backgroundImage = 'none';
      }
    });
  }

  /******************************** form validation submit events  *****************************************/
  else if(document.body.id == 'bd-submit-event') {
    //@TODO: need updated version of validate
//    jQuery('#user-data').validate({
//      errorElement: 'em',
//      errorClass: 'val-error',
//      //place the error em inside the label before any content
//      errorPlacement: function(error, invalidEl) {
//        invalidEl.parent('label').prepend(error);
//      },
//      highlight: function(invalidEl) {
//        jQuery(invalidEl).addClass('has-error');
//      },
//      unhighlight: function(invalidEl) {
//        jQuery(invalidEl).removeClass('has-error');
//      },
//      rules: {
//        'data[NewEvent][evtitle]' : {required: true},
//        'data[NewEvent][evpic1]' : {accept: 'zip|jpg|jpeg|png|gif'},
//        'data[NewEvent][evpic2]' : {accept: 'zip|jpg|jpeg|png|gif'},
//        'data[NewEvent][evstart_date]' : {date:true},
//        'data[NewEvent][evcity]' : {required: true},
//        'data[NewEvent][evsenderEmail]' : {required: true}
//      }
//    });
  }

  /****************************** toggle the display of the submit form in dossiers *************************************/
  //show the add comment form on click on 'add comment'
  else if(document.getElementById('add-dossier-comment')) {
    //hide the form if there is no form error
    var formObj = jQuery('#add-dossier-comment');
    if(!(jQuery('em', formObj).hasClass('val-error'))) {
      jQuery('#add-dossier-comment').hide();
    }

    jQuery('#add-comment-link').show().click(function() {
      var formObj = jQuery('#add-dossier-comment');
      if(formObj.is(':visible')) {
        formObj.slideUp('fast');
      }
      else{
        formObj.slideDown('fast');
      }
      return false;
    });
  }
  
  /********************************** the page with matching carpools *********************/
  else if(document.body.id == 'bd-similar-carpools') {
    addDetailsLink();
  }
  
  /**********************  verify sympass ********************/
  if(document.getElementById('sympass-data')) {
    verifySympass();
  }


  /******************************** autosubmit the pagelimit filter in event page ***********************************/
  jQuery('#EventPageLimitPagelimit').change(function() {
    this.form.submit();
  });

  // hint
  new inputHint();

  jQuery(document.body).resize(function(){
     jQuery('#dialog-cover').css('height' , '100%');
  });

  //open the popups for the partners
  jQuery('#partners a, #users a').click(openPartnerPopup);

  //the tracker on the banner
  jQuery('#banner-nopopup[target]').click(function() {
    var bannerName = this.name || 'banner';
    trackOutbound('/banner/' + bannerName);
  });

  //the tracker on moovijob
  jQuery('#bd-jobs div.jobbox a').click(function() {
    trackOutbound('/banner/moovijob');
  });  
  
  
  //position the google ads to their final position
  var adsArr = ['IMU', 'Skyscraper'];
  for(var i = 0; i < adsArr.length; i++) {
    var gAd = jQuery('#gAd-' + adsArr[i]);
    if(!gAd.length) {
      continue;
    }
    var gAdDummy = jQuery('#gAd-' + adsArr[i] + '-dummy');
    if(!gAdDummy.length) {
      continue;
    }
    var adOffset = gAdDummy.offset();
    gAd.css({position: 'absolute',
               zIndex : 99,
               left: adOffset.left + 'px',
               top:  adOffset.top + 'px'});
  }
});
//end of document load


//adds javascript action to buttons/images/...
jQuery.fn.addJsEvents = function() {
  jQuery('a.load-popup, button.load-popup', this).bind('click', popupLoader)
                                                 .ajaxStart(addWaitingCursor)
                                                 .ajaxStop(removeWaitingCursor);

   //the addjourneybutton needs a callback handler to handle validating the addresses
   var addJourneyParams = {};
   addJourneyParams.extraParams = {cb : manageAddJourneyPopup};
   jQuery('#addjourney-button, button.editjourney, #event-listing a.add-journey', this)
     .bind('click', addJourneyParams, popupLoader);

  //closes the opened journey details row
  jQuery('a.details-close', this).click(closeDetailsRow);

  //autocomplete the search for a user
  jQuery('#EvaluationCreatedForName, #FriendFriendName', this).autocomplete(ajaxUrl, {
    minChars : 2,
    extraParams : {action: 'acUser'}
  });

  //add the details opener for the profile
  jQuery('#profile-journeys').addDetailsOpener();

  return this;
};


//add an event to tr and opens the correlated details tr
jQuery.fn.addDetailsOpener = function() {
  return this.each(function() {
     //fetch all trs of the class has-details
     var elems = jQuery('#' + this.id + '>tbody>tr.has-details').css('cursor', 'pointer')
                                                   .unbind('click', toggleDetailsRow)
                                                   .click(toggleDetailsRow)
                                                   .find('input').click(function(e) {e.stopPropagation();}).end();
     
     /* the first link in the messages table just opens the message, so not stop the tr click */
     if(this.id == 'messages') {
       elems.find('a:not(a:first)').click(function(e) {e.stopPropagation();});
     }
     else{
       elems.find('a').click(function(e) {e.stopPropagation();});
     }
                                                   

     //add the hover for IE6
      if(jQuery.browser.msie && jQuery.browser.version.substr(0, 1) < 7) {
        jQuery('#' + this.id + '>tbody>tr.has-details', this).mouseover( function() {
                                                               jQuery(this).addClass('over');
                                                             })
                                                             .mouseout( function() {
                                                               jQuery(this).removeClass('over');
                                                             });
      }
  });
};



function toggleDetailsRow(e) {
  //get the id of the linked event
  var elem = null;
  if(this.tagName.toLowerCase() == 'a') {
    elem = jQuery(this).parents('tr');
  }
  else {
    elem      = jQuery(this);
  }
  var detailRow = jQuery('#' + elem.attr('id') + '_det');
  
  if(detailRow.css('display') && detailRow.css('display') != 'none') {
    detailRow.find('div.details-cont').fadeOut('normal', function(){detailRow.hide();
                                                                  elem.removeClass('active');
                                                                 });
  }
  else {
    //hide any open row
    elem.parent().find('tr.active').removeClass('active')
                                   .next('tr.details').hide()
                                   .find('div.details-cont').hide();
    //get the default display property of an existing table row
    var defaultTrDisplay = elem.addClass('active').css('display');

    //and show the details row
    detailRow.css('display', defaultTrDisplay)
             .find('div.details-cont').fadeIn('normal')
             //.link2Button()
             //.addJsEvents()
             ;
  }
  return false;
}

function closeDetailsRow() {
  var detailRow = jQuery(this).parents('tr');
  detailRow.find('div.details-cont').fadeOut('slow', function(){detailRow.hide().prev('tr.has-details')
                                                                                .removeClass('active');});
  return false;
}

function addWaitingCursor() {
  jQuery(this).css('cursor', 'wait');
}

function removeWaitingCursor() {
  jQuery(this).css('cursor', 'pointer');
}

//removes all open dialog boxes and hides the cover
function removeAllPopups() {
  jQuery('div.dialog').empty().remove();
  jQuery('#main').fadeIn(1);
  jQuery('#dialog-cover').hide();
}

//a wrapper for the managePopups function
function popupLoader(event) {
  var extraParams = false;
  var keepPopup   = false;

  if(event.data) {
    extraParams = event.data.extraParams || {};
    keepPopup   = event.data.keepPopup || false;
  }
  managePopups(this, extraParams, keepPopup);
  return false;
}

//manages opening and closing all popups
function managePopups(sender, extraParams, keepPopup) {
  //whether to keep the popups open or not
  keepPopup || removeAllPopups();

  var params = {};

  //we always need either an href attribute (for a link)
  //or a oldHref attribute (for a buttonified link)
  //or an action (for a form)
  params.href = sender.href || sender.oldHref || sender.action;
  
  if(!params.href) {
    return false;
  }

  //the action is whatever comes after the /actions/ part of the url
  //but the action might be followed by an id
  var actionPos    = params.href.lastIndexOf('/actions');
  var lastSlashPos = params.href.lastIndexOf('/');

  if(actionPos > 0) {
    params.action = params.href.substring(actionPos + 9, lastSlashPos);
  }
  
  
  if(!params.action) {
    return false;
  }

  if(extraParams) {
    jQuery(params, extraParams);
  }
  
  jQuery.ajax({
    data: params,
    success: function(data) {
      if(data.indexOf('dialog') > -1) {
        var tmp = document.createElement('div');
        tmp.innerHTML = data;
        var newDialog = jQuery('div.dialog', tmp);
        newDialog.makePopup();
        //if the params contain a callback function, execute this now
        if(typeof extraParams.cb == 'function') {
          extraParams.cb();
        }

        //if there is a form within the popup, set up ajaxsubmit the form
        newDialog.find('form').submit(function() {
          var options = {
            type : 'post',
            success: function(data) {
              //if it was a successful login, we often get two parts
              //those should be separated by __requestedPopup__
              //a) the contents of the user link box
              //b) the popup that was actually called
              var sepPosition = data.indexOf('__requestedPopup__');
              if(sepPosition > 0) {
                removeAllPopups();
                  jQuery('#mon-compte').html(data.substr(0, sepPosition));
                  var popupData = data.substr(sepPosition + 18);
                  if(popupData) {
                    jQuery(popupData).makePopup();
                    if(popupData.indexOf('id="add-journey"') > -1) {
                      manageAddJourneyPopup();
                    }
                  }
              }
              //if it is a dialog popup
              else if(data.indexOf('class="dialog') > -1) {
                keepPopup || removeAllPopups();
                jQuery(data).makePopup();

                //if it is a popup to add or edit journeys, call the appropriate function
                if(data.indexOf('id="add-journey"') > -1) {
                  manageAddJourneyPopup();
                }

              }
              //if we got some error messagess
              else if(data.indexOf('_json_') == 0) {
                var errorObj = eval('(' + data.substr(6) + ')');
                handleFormErrors(errorObj, newDialog);
              }
            },
            error: function() {
              jQuery('em.val-error').remove();
              jQuery('em.general-error', newDialog).html(__('An_error_has_occurred.'));
            }
          };
          jQuery(this).ajaxSubmit(options);
          return false;
        });
      }
      else if(data.indexOf('_json_') == 0) {
        return false;
        //eval the response and display the error message
        //var errorObj = eval('(' + data.substr(6) + ')');
        //handleFormErrors(errorObj, 'popup-' + popupName);
      }
    }
  });
  return false;
}

//handle any validation errors per javascript
function handleFormErrors(data, popupObject) {
  if(!isObject(data) || !isObject(popupObject)) {
    return false;
  }
  //remove all existing error messages
  jQuery('em.val-error').remove();
  jQuery('em.general-error').hide();
  var label = '';
  for(model in data) {
    if(!isObject(data[model])) {
      return false;
    }
    for(field in data[model]) {
      var fieldParts = field.split('_');
      if(fieldParts.length == 1 && fieldParts[0] == field) {
        jQuery('em.' + field + '.gen-error').html(data[model][field]).show();
      }
      else {
        var fieldId = model;
        for (var i = 0; i < fieldParts.length; i++) {
          fieldId += fieldParts[i].ucfirst();
        }
        //if we have a label, we want to insert the error message above the label text
        label = jQuery('#' + fieldId).parent('label');
        if(label.length) {
          label.prepend('<em class="val-error">' + (data[model][field]) + '</em>');
        }
        else {
          jQuery('#' + fieldId).before('<em class="val-error">' + (data[model][field]) + '</em>');
        }
      }
    }
  }
}

//used in manageJourneyPopup
function toggleJourneyType(show) {
  show = show || 1;
  if(show == 0) {
    jQuery('#addjourney-irregdate').show();
    jQuery('#addjourney-regdate').hide();
  }
  else {
    jQuery('#addjourney-irregdate').hide();
    jQuery('#addjourney-regdate').show();
  }
}

//used in manageJourneyPopup
function togglePassengerCnt(isDriver) {
  isDriver = isDriver || 0;
  if(isDriver == 0) {
    jQuery('#passenger_cnt').hide();
  }
  else {
    jQuery('#passenger_cnt').show();
  }
}

//used in manageJourneyPopup
function validateAddress() {
  var altText     = jQuery('#JourneyDepartureFull').attr('alt');
  var depAddress  = jQuery('#JourneyDepartureFull').val();
  var destAddress = 'none'; //do not geocode destination - this is used for events

  var destField   = document.getElementById('JourneyDestinationFull');
  if(destField) {
    destAddress = destField.value;
  }

  if(!depAddress || !destAddress || depAddress == altText || destAddress == altText) {
    return;
  }

  var params   = {};
  params.depAddress  = depAddress;
  params.destAddress = destAddress;
  params.action = 'geocodeAddress';
  jQuery.ajax({
    data: params,
    success: function(data) {
      jQuery('#address-selector').empty()
                                 .append(data)
                                 .show();
      jQuery('#JourneyAddressValidated').val('done');
      jQuery('#JourneyValidateAddress').text(__('revalidate_address'));
    }
  });
}

//fetches a select box with zones
function getZones() {
  if(!this.value) {
    return;
  }
  var cityField = this;
  var params   = {};
  params.cityName  = this.value;
  params.fieldName = this.id;
  params.action    = 'getZoningSelector';
  jQuery.ajax({
    data: params,
    success: function(data) {
      var exists = document.getElementById(cityField.id.replace('City', 'ZoneId'));
      //insert the select box at the end of the div for this address
      if(data) {
        //either replace an existing zoning
        if(exists) {
          jQuery(exists.parentNode).replaceWith(data);
        }
        //or add the new select to the form
        else{
          jQuery(cityField.parentNode.parentNode.parentNode).append(data);
        }
      }
      //remove the zoning
      else {
        if(exists) {
          jQuery(exists.parentNode).remove();
        }
      }
    }
  });
}

//manages the add/edit journey window
function manageAddJourneyPopup() {
  var jType = jQuery('#JourneyIsRegular').change(function() {
    toggleJourneyType(this.value);
  }).val();

  //remove the first option of the passengercnt box as this is only interesting without js
  jQuery('#passenger_cnt option:first').remove();

  var isDriver = jQuery('#JourneyIsDriver').change(function() {
    togglePassengerCnt(this.value);
  }).val();

  toggleJourneyType(jType);
  togglePassengerCnt(isDriver);

  /*************** onblur on the city fields fetch the zones *******************/
  jQuery('#JourneyDepartureCity, #JourneyDestinationCity').blur(getZones);

//  /***************** hide the help and display it on mouseover of the question mark ************/
//  jQuery('div.help').hide();
//
//  //add a question mark pic to the h4 in the add address part and show the help
//  jQuery('#addjourney-address h4 span').addClass('pic-help')
//  .mouseover(function() {
//    //the help div belonging to this h4
//    jQuery(this.parentNode).siblings('div.help').addClass('show-help').bgiframe().show();
//  })
//  .mouseout(function() {
//    //the help div belonging to this h4
//    jQuery(this.parentNode).siblings('div.help').hide();
//  });



  /************ the time picker for the add/edit journey time fields *************************/
  jQuery('#addjourney-time input.time').timePicker(copyTimes);
}

//manages the add/edit journey window
function manageAddJourneyPopupOri() {
  jQuery('#JourneyValidateAddress').show().click(validateAddress);

  jQuery('#JourneyDepartureFull, #JourneyDestinationFull').keypress(recheckValidation);

  var jType = jQuery('#JourneyIsRegular').change(function() {
    toggleJourneyType(this.value);
  }).val();

  //remove the first option of the passengercnt box as this is only interesting without js
  jQuery('#passenger_cnt option:first').remove();

  var isDriver = jQuery('#JourneyIsDriver').change(function() {
    togglePassengerCnt(this.value);
  }).val();

  toggleJourneyType(jType);
  togglePassengerCnt(isDriver);

  /************ the time picker for the add/edit journey time fields *************************/
  jQuery('#addjourney-time input.time').timePicker(copyTimes);
}

//function to open partner details popup
function openPartnerPopup() {
  var anchorPos = this.href.lastIndexOf('#');
  var leftPos = jQuery.browser.msie ? '300px' : '200px';

  if(anchorPos > -1) {
    var targetId = this.href.substring(anchorPos + 1);
    //hide any others
    jQuery('#popups div.dialog').hide();
    jQuery('#popups').show().find('#' + targetId)
                                  .addHider()
                                  .css({position : 'absolute',
                                        top  : (jQuery(document).scrollTop() + 50)*1 + 'px',
                                        left : leftPos})
                                  .show()
                                  .jqDrag('h2');
    return false;
  }
}


//updates the unread counters for the sidebar and the message center
function updateUnreadCounters(unreadCount) {
  unreadCount = unreadCount || 0;
  var sideBarCounter = jQuery('#unreadCountSide');
  var inboxCounter   = jQuery('#unreadCount');
  //if there are no unread messages
  if(!unreadCount || unreadCount < 1) {
    sideBarCounter.css('display', 'none');
    inboxCounter.css('display', 'none');
  }
  else{
    sideBarCounter.text(unreadCount);
    inboxCounter.text(unreadCount);
    sideBarCounter.css('display', 'inline');
    inboxCounter.css('display', 'inline');
  }
}

//@TODO: make this chainable and suitable for multiple objects
jQuery.myUpdater = {
  settings : {params : '',
		          delay  : '10000',
		          callback: function(){}},

	timeoutobj:  {id: -1},

  set: function(settings) {
		if (this.timeoutobj.id > -1) {
			clearTimeout(this.timeoutobj);
		}
    if (settings) {
        jQuery.extend(this.settings, settings);
    }
		this.timeoutobj.id = setTimeout("jQuery.myUpdater.beat();", this.settings.delay);
  },

  beat: function() {
		jQuery.ajax({
		    data: this.settings.params,
				success: function(data){
					if(typeof jQuery.myUpdater.settings.callback == 'function') {
					  jQuery.myUpdater.settings.callback(data);
					}
				}
		});
	  this.timeoutobj.id = setTimeout("jQuery.myUpdater.beat();", this.settings.delay);
  }
};

//adds the link for the details journey/events page to the entire table row
function addDetailsLink(table) {
  table      = table || 'journey';
  var rowObj = null;
  if(table == 'event') {
    //the link to the details of each event
   rowObj =  jQuery('#event-listing tr.has-details').css('cursor', 'pointer')
                                                    .css('cursor', 'hand')
                                                    .click(function() {
      //fetch the link target from the details link, the link has the class 'more-info'
      var aElems   = this.getElementsByTagName('a');
      var aElemsLength = aElems.length;
      if(aElems && aElemsLength) {
        for(var i = 0; i < aElemsLength; i++) {
          if(aElems[i].className.indexOf('more-info') > -1) {
            var detTarget = aElems[i].href;
            if(detTarget) {
              window.location.href = detTarget;
              break;
            }
          }
        }
      }
    });
  }
  else{
    //the link to the details of each journey
   rowObj =  jQuery('table.journey-table tr.has-details').css('cursor', 'pointer')
                                            .css('cursor', 'hand')
                                            .click(function() {
      //fetch the link target from the details link
      var aElems = this.getElementsByTagName('a');
      if(aElems && aElems.length) {
        //the last link the table row is the details link
        var detailA = aElems[aElems.length - 1];
        if(detailA) {
          var detTarget = detailA.href;
          if(detTarget) {
            window.location.href = detTarget;
          }
        }
      }
    });
  }

  rowObj.jIf(jQuery.browser.msie && jQuery.browser.version.substr(0, 1) < 7).mouseover( function() {
                                                             jQuery(this).addClass('over');
                                                           })
                                                           .mouseout( function() {
                                                             jQuery(this).removeClass('over');
                                                           });
}

//initiate sympass verification
function verifySympass() {
  var params    = {};
  params.action = 'verifySympass';
  jQuery.ajax({
    data: params,
    success: function(data) {
      //if verification is ok, set iframe source accordingly
      if(data.length > 2) {
        jQuery('#sympass-verify').hide();
        jQuery('#sympass-data iframe').attr('src', data).show();
      }
      else{
        jQuery('#sympass-verify').hide();
        jQuery('#sympass-verify-failed').show();
      }
    },
    error: function(data) {
      jQuery('#sympass-verify').hide();
      jQuery('#sympass-verify-failed').show();
    }
  });
}