var AdviceType = {
	Advice_Intersection     : 0, 
	Advice_ConfirmationPOI  : 1, 
	Advice_ConfirmationHighwayIntersection : 2,
	Advice_StartRouteAdvice : 3
};

var NearbyPoiRelation = {
	Poi_None            : 0, 
	Poi_BeforeAdvice    : 1, 
	Poi_AtAdvice        : 2, 
	Poi_AfterAdvice     : 3
};	

var NearbyPoiType = {
	Poi_Stadium					: 480,
	Poi_Hotel					: 450,
	Poi_Restaurant				: 460,
	Poi_Rentacar				: 620,
	Poi_Pharmacy				: 562,
	Poi_Hospital				: 560,
	Poi_PetrolStation			: 610,
	Poi_ShoppingCenter			: 470,
	Poi_VehicleRepair			: 600,
	Poi_Embassy					: 506,
	Poi_Church					: 540,
	Poi_CarDealer				: 670,
	Poi_Bank					: 580,
	Poi_Mosque					: 541,
	Poi_Hindu					: 545,
	Poi_Temple					: 542,
	Poi_Shopping				: 838
};

var SimpleAdvice = {
	adv_invalid             : -1,
	adv_sharp_right         : 0,
	adv_right               : 1,
	adv_bear_right          : 2,
	adv_straight_ahead      : 3,
	adv_bear_left           : 4,
	adv_left                : 5,
	adv_sharp_left          : 6,
	adv_turn_around         : 7,
	adv_enter_round_about   : 8,
	adv_round_about_1       : 9,
	adv_round_about_2       : 10,
	adv_round_about_3       : 11,
	adv_round_about_4       : 12,
	adv_round_about_5       : 13,
	adv_round_about_6       : 14,
	adv_round_about_7       : 15,
	adv_round_about_8       : 16,
	adv_shift_right         : 17,
	adv_shift_left          : 18,
	adv_take_highway_exit   : 19,
	adv_destination_reached : 20,
	adv_take_ferry          : 24
};

var IntersectionShape = {
	IntersectionShape_Unknown   : 0, 
	IntersectionShape_T         : 1, 
	IntersectionShape_Y         : 2
};

var WorldOrientation = {
	Orientation_Unknown     : 0,
	Orientation_North       : 1, 
	Orientation_NorthEast   : 2, 
	Orientation_East        : 3, 
	Orientation_SouthEast   : 4,
	Orientation_South       : 5, 
	Orientation_SouthWest   : 6, 
	Orientation_West        : 7, 
	Orientation_NorthWest   : 8
};

var PoiRelationToRoad = {
	PoiRoad_None    : 0, 
	PoiRoad_Left    : 1, 
	PoiRoad_Right   : 2
};

var EnglishAdvisor = {
    advice_to_text : function(advice) {
        var advice_text = "";
        switch (advice.advice_type) {
            case AdviceType.Advice_Intersection: advice_text = this.intersection_advice_to_text(advice); break;
            case AdviceType.Advice_ConfirmationPOI: advice_text = this.confirmation_poi_advice_to_text(advice); break;
            case AdviceType.Advice_ConfirmationHighwayIntersection : advice_text = this.confirmation_highway_advice_to_text(advice); break;
            case AdviceType.Advice_StartRouteAdvice: advice_text = this.start_advice_to_text(advice); break;
        }
        
        // capitalize the first letter, skip over HTML tags, add "." to finish the sentence.
        var i = 0;
        if (advice_text.charAt(0) == '<') {
            while (advice_text.charAt(i) != '>') i++;
            i ++;
        }
        
        if (advice_text.charAt(advice_text.length - 1) == " ")
            advice_text = advice_text.substr(0, advice_text.length - 1);
        
        return advice_text.substr(0, i) + advice_text.charAt(i).toUpperCase() + advice_text.substr(i+1) + ".";

    },
    
    intersection_advice_to_text  : function(advice) {
        var advice_text = "";
        var used_word_at = false;
        var has_good_highway_advice = false;
        var manouver_text_added = false;
        
        if (advice.manouver == SimpleAdvice.adv_destination_reached)
			return "destination reached";
			
		// special handling for "take ferry" advices
		if (advice.manouver == SimpleAdvice.adv_take_ferry) {
		    advice_text = "<b>take ferry</b> ";
		    if (advice.location_name.length > 0)
		        advice_text += "<i>" + advice.location_name + "</i> ";
		    advice_text += "from <i>" + advice.entry_road_name + "</i> to <i>" + advice.exit_road_name + "</i>";
		    return advice_text;
		}

		// create the advice prefix: "at next intersection", "at exit E12", "at highway intersection I55", "at T-shaped intersection"
    	if (advice.first_intersection_from_prev_advice) {
			if (this.is_roundabout_advice(advice.manouver) == false)	{
				advice_text = "at next intersection ";
				used_word_at = true;
			}
		} else if (advice.signpost_exit_number.length > 0) {
			if (this.is_roundabout_advice(advice.manouver) == false) {
				advice_text = "at exit <i>" + advice.signpost_exit_number + "</i> ";
				used_word_at = true;

				if (advice.location_name.length > 0)
					advice_text += "(<i>" + advice.location_name + "</i>)";

				has_good_highway_advice = true;
			}
		} else if ((advice.manouver == SimpleAdvice.adv_take_highway_exit) && (advice.location_name.length > 0)) {
			advice_text = "at highway intersection <i>" + advice.location_name + "</i> ";
			has_good_highway_advice = true;
		} else if (advice.intersection_shape == IntersectionShape.IntersectionShape_T) {
			if (this.is_roundabout_advice(advice.manouver) == false) {
				advice_text = "at the end of the road ";
				used_word_at = true;
			}
		} else if (advice.intersection_shape == IntersectionShape.IntersectionShape_Y) {
			if (this.is_roundabout_advice(advice.manouver) == false) {
				advice_text = "at fork ";
				used_word_at = true;
			}
		}		

		// additional advice prefix: "after gas station", "at McDonalds restaurant", "take the 2nd left turn"
		if (has_good_highway_advice == false) {
			if (advice.poi_relation_to_advice == NearbyPoiRelation.Poi_BeforeAdvice) {
				advice_text = "after " + this.get_poi_description(advice.poi_description.type_ID, advice.poi_description.brand_name) + " ";
			} else if (advice.poi_relation_to_advice == NearbyPoiRelation.Poi_AtAdvice) {
				advice_text = "at " + this.get_poi_description(advice.poi_description.type_ID, advice.poi_description.brand_name) + " ";
				used_word_at = true;
			} else if ((advice.manouver == SimpleAdvice.adv_left) && (advice.num_left_roads_since_prev_advice != -1)) {
				advice_text = "take the " + this.create_ordinal_string(advice.num_left_roads_since_prev_advice + 1) + " <b>left</b>";
				manouver_text_added = true;
			} else if ((advice.manouver == SimpleAdvice.adv_right) && (advice.num_right_roads_since_prev_advice != -1)) {
				advice_text = "take the " + this.create_ordinal_string(advice.num_right_roads_since_prev_advice + 1) + " <b>right</b>";
				manouver_text_added = true;
			}
		}


		// add the manouver text: "turn left", "turn left, then turn right"
		if (manouver_text_added == false) 
		    advice_text += this.simple_advice_to_text(advice.manouver);

		if (advice.immediate_follow_manouver != SimpleAdvice.adv_invalid) 	{
			if (advice.immediate_follow_manouver != SimpleAdvice.adv_destination_reached)
				advice_text += ", then ";
			else
				advice_text += " and ";

			if (advice.manouver == advice.immediate_follow_manouver)
				advice_text += "again ";
			
			advice_text += this.simple_advice_to_text(advice.immediate_follow_manouver) + " ";

			if (advice.immediate_follow_manouver == SimpleAdvice.adv_destination_reached)
				return advice_text;
		} else {
			advice_text += " ";
		}
		

		// add the street names
		if (advice.merge_onto_highway) {
			if (advice.signpost_label.length > 0)
				advice_text += "towards <i>" + advice.signpost_label + "</i> ";

			advice_text += "and merge on ";
			if (advice.exit_road_name.length > 0)			
				advice_text += "<i>" + advice.exit_road_name + "</i> ";
			advice_text += "highway ";
		} else {
			if (advice.signpost_label.length > 0) {
				advice_text += "towards <i>" + advice.signpost_label + "</i> ";
			} else if ((advice.manouver != SimpleAdvice.adv_straight_ahead) && (advice.manouver != SimpleAdvice.adv_turn_around)) {
				if ((advice.entry_road_name == advice.exit_road_name) && (advice.entry_road_name.length > 0))
				{
					advice_text += "to stay on <i>" + advice.exit_road_name + "</i> ";
				} else if (advice.exit_road_name.length > 0) {
					if (used_word_at)
						advice_text += "onto ";
					else
						advice_text += "at ";

					advice_text += "<i>" + advice.exit_road_name + "</i> ";
				}
			} else if (advice.manouver == SimpleAdvice.adv_straight_ahead) {
				if ((advice.entry_road_name == advice.exit_road_name) && (advice.entry_road_name.length > 0)) {
					advice_text += "to stay on <i>" + advice.exit_road_name + "</i> ";
				} else if (advice.exit_road_name.length > 0) {
					advice_text += "on ";				
					advice_text += "<i>" + advice.exit_road_name + "</i> ";
				}
			} else if (advice.manouver == SimpleAdvice.adv_turn_around)	{
				if ((advice.location_name.length > 0) && (used_word_at))
					advice_text += "at <i>" + advice.location_name + "</i> ";
			}

			// add landmarks after intersection
			if (advice.poi_relation_to_advice == NearbyPoiRelation.Poi_AfterAdvice) {
				advice_text += " and you will pass by " + this.get_poi_description(advice.poi_description.type_ID, advice.poi_description.brand_name) + " ";
				if (advice.poi_description.relation_to_road == PoiRelationToRoad.PoiRoad_Left)
				    advice_text += "on your left";
			    if (advice.poi_description.relation_to_road == PoiRelationToRoad.PoiRoad_Right)
				    advice_text += "on your right";
			}
		}

		return advice_text;
    },
    
    confirmation_poi_advice_to_text  : function(advice) {
    	var advice_text = "";
    	
    	if (advice.poi_relation_to_advice == NearbyPoiRelation.Poi_AtAdvice) {
			if (advice.entry_road_name.length > 0)
				advice_text = "while driving on <i>" + advice.entry_road_name + "</i> ";

			advice_text += "you will pass by " + this.get_poi_description(advice.poi_description.type_ID, advice.poi_description.brand_name) + " ";
			
			if (advice.poi_description.relation_to_road == PoiRelationToRoad.PoiRoad_Left)
				advice_text += "on your left";
			if (advice.poi_description.relation_to_road == PoiRelationToRoad.PoiRoad_Right)
				advice_text += "on your right";
		}

		return advice_text;
    },
    
    confirmation_highway_advice_to_text  : function(advice) {
        var advice_text = "";
        
        if (advice.poi_relation_to_advice == NearbyPoiRelation.Poi_BeforeAdvice)
		    advice_text = "after " + this.get_poi_description(advice.poi_description.type_ID, advice.poi_description.brand_name) + " ";
		else if (advice.poi_relation_to_advice == NearbyPoiRelation.Poi_AtAdvice)
			advice_text = "at " + this.get_poi_description(advice.poi_description.type_ID, advice.poi_description.brand_name) + " ";

		advice_text += "you will pass highway intersection <i>" + advice.location_name + "</i> ";

		return advice_text;
    },
    
    start_advice_to_text  : function(advice) {
        var advice_text = "";
        if (advice.border_crossing_name.length > 0)
            advice_text = "<b>cross the border</b> to <i>" + advice.border_crossing_name + "</i>. Continue ";
        else
            advice_text = "head ";
            
        if (advice.start_orientation != WorldOrientation.Orientation_Unknown)
			advice_text += " <b>" + this.get_orientation_text(advice.start_heading) + "</b> ";
		else if (advice.location_name.length > 0)
			advice_text = "start ";

		if (advice.entry_road_name.length > 0)
			advice_text += "on <i>" + advice.entry_road_name + "</i> ";

		if (advice.location_name.length > 0)
			advice_text += "towards <i>" + advice.location_name + "</i> ";

		if (advice_text.length == 0) // this shouldn't happen, just in case
			advice_text = "begin the journey";

		if (advice.immediate_follow_manouver != SimpleAdvice.adv_invalid)
		{
			if ((advice.immediate_follow_manouver == SimpleAdvice.adv_destination_reached) ||
			    (this.is_roundabout_advice(advice.immediate_follow_manouver)))
				advice_text += " and ";
			else
				advice_text += " then ";
		
			advice_text += this.simple_advice_to_text(advice.immediate_follow_manouver) + " ";
			
			if (this.is_roundabout_advice(advice.immediate_follow_manouver))
			    advice_text += " from the roundabout";
		}

		return advice_text;
    },
    
    
    
    get_poi_description : function(poi_type_ID, brand_name) {
	    switch (poi_type_ID) {
	        case NearbyPoiType.Poi_Stadium:         return "a stadium";
	        case NearbyPoiType.Poi_Hotel:           return "<i>" + brand_name + "</i> hotel";
	        case NearbyPoiType.Poi_Restaurant:      return "<i>" + brand_name + "</i> restaurant";
	        case NearbyPoiType.Poi_Rentacar:        return "<i>" + brand_name + "</i> rent-a-car";
	        case NearbyPoiType.Poi_Pharmacy:        return "a pharmacy";
	        case NearbyPoiType.Poi_Hospital:        return "a hospital";
	        case NearbyPoiType.Poi_PetrolStation:   return "<i>" + brand_name + "</i> petrol station";
	        case NearbyPoiType.Poi_ShoppingCenter:  return "a shopping center";
	        case NearbyPoiType.Poi_VehicleRepair:   return "<i>" + brand_name + "</i> vehicle repair";
	        case NearbyPoiType.Poi_Embassy:         return "<i>" + brand_name + "</i> embassy";
	        case NearbyPoiType.Poi_Church:          return "a church";
	        case NearbyPoiType.Poi_CarDealer:       return "<i>" + brand_name + "</i> car dealer";
	        case NearbyPoiType.Poi_Bank:            return "<i>" + brand_name + "</i> bank";
	        case NearbyPoiType.Poi_Mosque:			return "a mosque";
			case NearbyPoiType.Poi_Hindu:			return "<i>" + brand_name + "</i>"; // "a mandir";
			case NearbyPoiType.Poi_Temple:			return "a temple";
			case NearbyPoiType.Poi_Shopping:		return "<i>" + brand_name + "</i> shopping center";
	    }
	    return "";
    },

    simple_advice_to_text : function(simpleAdvice) {            
	    switch (simpleAdvice) {
	        case SimpleAdvice.adv_sharp_right:          return "make <b>sharp right</b> turn";
	        case SimpleAdvice.adv_right:                return "turn <b>right</b>";
	        case SimpleAdvice.adv_bear_right:           return "<b>bear right</b>";
	        case SimpleAdvice.adv_straight_ahead:       return "continue <b>straight</b>";
	        case SimpleAdvice.adv_bear_left:            return "<b>bear left</b>";
	        case SimpleAdvice.adv_left :                return "turn <b>left</b>";
	        case SimpleAdvice.adv_sharp_left:           return "make <b>sharp left</b> turn";
	        case SimpleAdvice.adv_turn_around:          return "make <b>U-turn</b>";
	        case SimpleAdvice.adv_enter_round_about:    return "<b>enter</b> the roundabout";
	        case SimpleAdvice.adv_round_about_1:        return "take <b>1st</b> exit";
	        case SimpleAdvice.adv_round_about_2:        return "take <b>2nd</b> exit";
	        case SimpleAdvice.adv_round_about_3:        return "take <b>3rd</b> exit";
	        case SimpleAdvice.adv_round_about_4:        return "take <b>4th</b> exit";
	        case SimpleAdvice.adv_round_about_5:        return "take <b>5th</b> exit";
	        case SimpleAdvice.adv_round_about_6:        return "take <b>6th</b> exit";
	        case SimpleAdvice.adv_round_about_7:        return "take <b>7th</b> exit";
	        case SimpleAdvice.adv_round_about_8:        return "take <b>8th</b> exit";
	        case SimpleAdvice.adv_take_highway_exit:    return "<b>leave</b> the highway";
	        case SimpleAdvice.adv_destination_reached:  return "you will reach your destination";
	    }
	    return "";
    },

    is_roundabout_advice : function (simpleAdvice) {
	    switch (simpleAdvice) {
	        case SimpleAdvice.adv_round_about_1:
	        case SimpleAdvice.adv_round_about_2:
	        case SimpleAdvice.adv_round_about_3:
	        case SimpleAdvice.adv_round_about_4:
	        case SimpleAdvice.adv_round_about_5:
	        case SimpleAdvice.adv_round_about_6:
	        case SimpleAdvice.adv_round_about_7:
	        case SimpleAdvice.adv_round_about_8:
		        return true;
	    }
	    return false;
    },

    get_orientation_text : function(orientation) {
	    switch(orientation) {
	        case WorldOrientation.Orientation_North:        return "north";
	        case WorldOrientation.Orientation_NorthEast:    return "north-east";
	        case WorldOrientation.Orientation_East:         return "east";
	        case WorldOrientation.Orientation_SouthEast:    return "south-east";
	        case WorldOrientation.Orientation_South:        return "south";
	        case WorldOrientation.Orientation_SouthWest:    return "south-west";
	        case WorldOrientation.Orientation_West:         return "west";
	        case WorldOrientation.Orientation_NorthWest:    return "north-west";
	    }
	    return "";
    },

    create_ordinal_string : function(ordinal_num) {
	    switch(ordinal_num) {
	        case 1: return "1st";
	        case 2: return "2nd";
	        case 3: return "3rd";
	        case 4: return "4th";
	        case 5: return "5th";
	    }
	    return "";
    }
};

