
/////////////////////////////////
//  Routing behavior for retail locator
//  author paul irish
////////////////////////////////

/*
TODO:

- error handling on lookup fail.
- i18n


*/


var routing = {
  
  route_finder      : null, // setin callRoute()
  max_zindex        : 2000,
  $tbody            : null, // set in viewDirectionsFor()
  counter_requested : null, // set in viewDirectionsFor()
  isReverse         : false,
  inRoutingState    : false, // used to determine state. set right before external call fired. cleared in timeout timer.
  markers           : []  

};


// route is a global. 

routing.viewDirectionsFor = function(elem,counternum){
  
  $('#dir-address-origin').val( $('#map-address').val() );
  $('#dir-country-origin').val( $('#map-country').val() );
  
  if (RBK.i18n.retailLocator.locale == 'en_US'){RBK.i18n.retailLocator.languageCode = 'us'};
  if (RBK.i18n.retailLocator.locale == 'en_GB'){RBK.i18n.retailLocator.languageCode = 'gb'};
    
  $('#lang-origin').val( RBK.i18n.retailLocator.languageCode  );
   
  if (locator.isInputVerbose){ // copy over the rest of the elements, too.
    
  }
  
  routing.$tbody = $(elem).parents('tbody:first');
  
  $('#oldTbody').removeAttr('id');
  
  $('tr#directions-destination').appendTo(routing.$tbody).show();
  $.scrollTo( '+=' + $('#directions-destination').height() , 500 );

  
  //save the dir link to access him later.
  
  
  routing.counter_requested = counternum; // set the page we want to view
  return false;
}






routing.callRoute = function() {
  
    $('tr#directions-destination').parent().attr('id','oldTbody');
      
    $('tr#directions-destination').hide().appendTo('#directions-destination-table tbody'); // move it so we can get it back.
    
    
    $('#geo-error,#error,#timeout-error').hide();
    $('#mapresults, div.pagination').hide();
    
    // load up the locations array with two (or more) MMLocations in the order that you want the directions
    // then call route_finder.request()
    
    routing.locations = [];
    
    
    // origin address first
    var qs = $('#dir-address-origin').get(0);
    var address = new MMAddress();
  	if (qs.value != '') {
      	address.qs = qs.value;
      	address.country_code = $('#dir-country-origin').val();
    }
    routing.locations.push(new MMLocation(address));

    // destination address
    for (var i = 0, recs = searcher.all_records, len = recs.length; i<len; i++){
      if (recs[i].counter == routing.counter_requested){                                  // WARNING: since this is now using the smushed all_records, this freaks me out.
        // THIS IS THE ADDRESS
        routing.locations.push(new MMLocation(new MMLatLon( recs[i].point.lat , recs[i].point.lon )));
      }
    }

    routing.fireLookup(routing.locations);
}

routing.fireLookup = function(locations){
  
    route = new MMRoute( locations );


    // CLEAN UP 
    var $trs = $('#direction-steps-tbody > tr');
    $trs.slice(1, $trs.length).remove();
    
    $('#routeSteps > p').remove();
    
    //locator.mapviewer.removeAllOverlays();
    $.each(routing.markers, function(){
      locator.mapviewer.removeOverlay( this );
    });
    routing.markers = []; // clear it.
    
    $.each(locator.markers, function(){
      this.setVisibility(false);
      
      
    });
  
    // set the language
    route.lang = $('#lang-origin').val(); // gb was normalize in the onload()
  
    routing.inRoutingState = true;
    locator.timeoutTimer.start(); // protect against MM's slow server
     
    routing.route_finder.request(route);
    
    
}

routing.resultsLoaded = function() {
    
    locator.timeoutTimer.clear(); 
    
   
    if (route.error_code) {
    	$('#mapresults, div.pagination').show(); 
  		
  		$('tr#directions-destination').appendTo('#oldTbody').show();
  		
  		//route.error_code route.error_explanation
  		$('#geo-error').show();
  		
    } else { // got directions back successfully!
      
        if (routing.isReverse){      
          var ending = routing.reverseBlock2;
          var starting =       routing.reverseBlock1;
          routing.isReverse = false;  
   
        } else {
           var ending = routing.$tbody.find('td.adr').eq(0).html();
           var starting = $('#dir-address-origin').val(); // + '<br/>' + $('dir-country-origin').val()
        }   
        var dirhtml = '<h3>'+RBK.i18n.retailLocator.routeStartLoc+'</h3><blockquote>' + starting + '</blockquote>' +
                      '<h3>'+RBK.i18n.retailLocator.routeEndLoc+'</h3><blockquote>' + ending + '</blockquote>';
        
        $('<div id="dir-summary">').html(dirhtml).prependTo('#search-config');
       
       
        $('#map-search').hide();
        
        
        // clear the markers that were already there.
        //locator.mapviewer.removeAllOverlays();
        
        // use getAutoScaleLocation to show the entire route on the map, with the route bounds:
        
		    locator.mapviewer.goToPosition( locator.mapviewer.getAutoScaleLocation( route.bounds ) );
         
        $('table#results').hide();
    
    
        routing.displayStages(route);
        // Show the route on the map with PolyLines, by adding each polyline returned:
        for( var i = 0, l = route.polyLine.length; i < l; ++i ) {
          route.polyLine[i].reset(route.polyLine[i].points, {'opacity':0.6, 'color':'#00FF00', 'thickness':2.0});
          
          locator.mapviewer.addOverlay(route.polyLine[i]);
        }
    }

}


routing.displayStages = function(route) {
    var curr_step = 1;
    var stages = route.stages; 
    var container = document.getElementById('routeSteps');

    var summary = '<h3>'+RBK.i18n.retailLocator.routeETT+'</h3><blockquote>';
    if (route.duration.days > 0) { summary += route.duration.days + RBK.i18n.retailLocator.routeDays; }
    if (route.duration.hours > 0) { summary += route.duration.hours + RBK.i18n.retailLocator.routeHours; }
    if (route.duration.minutes > 0) { summary += route.duration.minutes + RBK.i18n.retailLocator.routeMin; }
    
    if (RBK.i18n.retailLocator.isKm) {
        summary += RBK.i18n.retailLocator.routeFor + route.distance.miles + ' ' + RBK.i18n.retailLocator.kilometers;
    } else { // probably mi
        summary += RBK.i18n.retailLocator.routeFor + route.distance.miles + ' ' + RBK.i18n.retailLocator.routeMiles;
    }     
    

    summary += '</blockquote><br/><br/><div class="clearfix"><a href="#" onclick="return routing.reverseDirs();" class="SDbutton"><span>'+RBK.i18n.retailLocator.routeRevDir+'</span></a></div>';
    summary += '<div class="clearfix" style="clear:left"><a href="#" onclick="return routing.getOtherDirs();" class="SDbutton"><span>'+RBK.i18n.retailLocator.routeAddRet+'</span></a></div>';
        
    $("<div/>").html(summary).appendTo('#dir-summary');
    
    var steps = stages[0].steps; // only one stage! hardcoded. stage example here: http://www.multimap.com/share/documentation/api/1.2/demos/routing.htm

    // Now we will display each step instruction within this stage:
    for (var stepCount=0; stepCount < steps.length; stepCount++) {
        // Label the current marker with the step number:
        var text = curr_step;
        // Make the higher numbered step markers appear 'on top of' lower ones:
        var zindex = routing.max_zindex - curr_step + 1;
        
        // Use 'S' as marker text if this is the first step of the entire route:
        if (stepCount  == 0) {
            text = 'S';
        }        
        // Use 'F' as marker text if this is the last step of the entire route:      
        if (stepCount  == steps.length - 1) {
            text = 'F';
            zindex = routing.max_zindex; 
       }                
        // Create a written 'instruction' using the roadname and/ or roadnumber:
        var instruction = steps[stepCount].instruction;
        var roadname = steps[stepCount].road_name;
        var roadnumber = steps[stepCount].road_number; 
        
        var TDcount = document.createElement('td');
        TDcount.innerHTML = curr_step;
        
        var TDinstr = document.createElement('td');
        var TDdist = document.createElement('td');

        if (roadname && roadnumber) {
            instruction += ' ' + roadname + ' (' + roadnumber + ') ';
        } else if (roadname) {
            instruction += ' ' + roadname + ' ';
        } else if (roadnumber) {
            instruction += ' ' + roadnumber + ' ';
        }
        
        // Show the distance of this particular step:
        var distance = '';
        if (RBK.i18n.retailLocator.isKm) {
            distance += steps[stepCount].distance.km +' '+RBK.i18n.retailLocator.kilometers;
        } else { // probably mi
            distance += steps[stepCount].distance.miles+' '+RBK.i18n.retailLocator.miles; 
        }                    
        
        TDinstr.innerHTML = instruction;
        TDdist.innerHTML = (steps[stepCount].distance.miles > 0) ? distance : '';
        var rowTR = document.createElement('tr');
        rowTR.appendChild(TDcount);
        rowTR.appendChild(TDinstr);
        rowTR.appendChild(TDdist);
        
        document.getElementById('direction-steps-tbody').appendChild(rowTR);
        
        // Create the step marker, using the instruction and marker text we previously created:
        routing.createStepMarker(steps[stepCount].start_point, instruction, text, zindex);
        
        ++curr_step;
    }

               
    $('#direction-steps').show();
    $('#routeSteps').show();
    $('mapviewer,div.pagination').hide();
    
    
    // Add copyright and disclaimer, as required:
    var copyright = '';
    if (route.copyright) {copyright += RBK.i18n.retailLocator.copyRight + route.copyright; }
    if (route.disclaimer)  {copyright += '<br />'+RBK.i18n.retailLocator.disclaimer+'<a href="' + route.disclaimer +'">' + route.disclaimer +'<' + '/a>'; }
    
    $('<p/>').addClass('disclaimer').html(copyright).appendTo(container);
    
}

routing.reverseDirs = function(){
  
  routing.isReverse = true;
  var $block1 = $('#dir-summary blockquote:first');
  var $block2 = $('#dir-summary blockquote').eq(1);
  var block1html = $block1.html();
  routing.reverseBlock1 = $block2.html();
  routing.reverseBlock2 = block1html;
  
  $('#loading').show();
  
  $('#dir-summary').remove();
  
  $.each(routing.markers, function(){ // remove the existing direction markers
    locator.mapviewer.removeOverlay( this );
  });
  routing.markers = []; // clear it.
  $.each(route.polyLine, function(){ // remove all the polylines
    this.remove();
  });   
  routing.fireLookup(routing.locations.reverse());
  
  return false;
}

routing.getOtherDirs = function(){
  $('#mapresults div.pagination').show();
  $('table#results').show(); 
  $('div#routeSteps').hide();
  
  $('#directions-destination').hide();
  
   $('#mapresults,div.pagination').show();
   
  $('div#dir-summary').remove();
  $('form#map-search').show();
  
  
  $.each(routing.markers, function(){ // remove the existing direction markers
    locator.mapviewer.removeOverlay( this );
    
  });
  routing.markers = []; // clear it.
  $.each(route.polyLine, function(){ // remove all the polylines
    this.remove();
  });   
  
  $.each(locator.markers, function(){ // SHOW the store markers
    this.setVisibility(true);
  });

  locator.mapviewer.goToPosition ( locator.mapviewer.getAutoScaleLocation( locator.markers ) );  // center the map
  
  return false;
}
    
routing.createStepMarker = function(location, instruction, text, zindex) {
    routing.markers.push( locator.mapviewer.createMarker(location, {zIndex: zindex, 'text' : text}) );
    routing.markers[ routing.markers.length-1 ].setInfoBoxContent('<p>' + instruction + '<' + '/p>');
}        



// onload events
$( function(){
    
  var SL = RBK.i18n.retailLocator;
  if (SL.languageCode == 'en_us'){SL.languageCode = 'us'};
  if (SL.languageCode == 'en_gb'){SL.languageCode = 'gb'};
  $('#lang').val(SL.languageCode);
  
  $('#directions-destination a.cancel').click(function(){
    $('tr#directions-destination').hide();
  });
  
  $('#directions-destination form').submit( function(){
    $('#loading').show();
    routing.callRoute();
    return false;
  });
  
  $('#directions-destination a.submit').click( function(){
    $(this).parents('form:first').submit();
  });
  
  $('#directions-destination input[type="text"],#directions-destination select').keydown(function(e){
    if (e.keyCode == 13) { $(this).parents('form:first').submit(); }
  });
  
    
    
  routing.route_finder= new MMRouteRequester( routing.resultsLoaded );  
  
});


/**
 * jQuery.ScrollTo - Easy element scrolling using jQuery.
 * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
 * http://plugins.jquery.com/project/scrollto/ 
 * usage: $.scrollTo( '#target-examples', 800, {easing:'elasout'} );
 * or $.scrollTo( '+=100', 500 );
  * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Date: 2/19/2008
 * @author Ariel Flesler
 * @version 1.3.3
 */
(function($){var o=$.scrollTo=function(a,b,c){o.window().scrollTo(a,b,c)};o.defaults={axis:'y',duration:1};o.window=function(){return $($.browser.safari?'body':'html')};$.fn.scrollTo=function(l,m,n){if(typeof m=='object'){n=m;m=0}n=$.extend({},o.defaults,n);m=m||n.speed||n.duration;n.queue=n.queue&&n.axis.length>1;if(n.queue)m/=2;n.offset=j(n.offset);n.over=j(n.over);return this.each(function(){var a=this,b=$(a),t=l,c,d={},w=b.is('html,body');switch(typeof t){case'number':case'string':if(/^([+-]=)?\d+(px)?$/.test(t)){t=j(t);break}t=$(t,this);case'object':if(t.is||t.style)c=(t=$(t)).offset()}$.each(n.axis.split(''),function(i,f){var P=f=='x'?'Left':'Top',p=P.toLowerCase(),k='scroll'+P,e=a[k],D=f=='x'?'Width':'Height';if(c){d[k]=c[p]+(w?0:e-b.offset()[p]);if(n.margin){d[k]-=parseInt(t.css('margin'+P))||0;d[k]-=parseInt(t.css('border'+P+'Width'))||0}d[k]+=n.offset[p]||0;if(n.over[p])d[k]+=t[D.toLowerCase()]()*n.over[p]}else d[k]=t[p];if(/^\d+$/.test(d[k]))d[k]=d[k]<=0?0:Math.min(d[k],h(D));if(!i&&n.queue){if(e!=d[k])g(n.onAfterFirst);delete d[k]}});g(n.onAfter);function g(a){b.animate(d,m,n.easing,a&&function(){a.call(this,l)})};function h(D){var b=w?$.browser.opera?document.body:document.documentElement:a;return b['scroll'+D]-b['client'+D]}})};function j(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);
