/// <summary>
		/// Invoked when this page is about to be displayed in a Frame.
		/// </summary>
		/// <param name="e">Event data that describes how this page was reached.
		/// This parameter is typically used to configure the page.</param>
		protected override void OnNavigatedTo(NavigationEventArgs e)
		{
			Windows.Phone.UI.Input.HardwareButtons.BackPressed += HardwareButtons_BackPressed;

			searchresult = e.Parameter as BusGroup;
			this.DefaultViewModel["SearchResult"] = searchresult;
		}
        /// <summary>
        /// Populates the page with content passed during navigation. Any saved state is also
        /// provided when recreating a page from a prior session.
        /// </summary>
        /// <param name="sender">
        /// The source of the event; typically <see cref="NavigationHelper"/>.
        /// </param>
        /// <param name="e">Event data that provides both the navigation parameter passed to
        /// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested and
        /// a dictionary of state preserved by this page during an earlier
        /// session. The state will be null the first time a page is visited.</param>
        private async void NavigationHelper_LoadState(object sender, LoadStateEventArgs e)
        {
			datagroup = await SampleDataSource.GetItemsAsync();
			loadJSONprogressbar.Opacity = 0;
			this.DefaultViewModel[FirstGroupName] = datagroup;
        }
		private void Button_RouteSearch_Click(object sender, RoutedEventArgs e)
		{
			BusGroup listbus = new BusGroup();
			if (inputfromsearch.Text != "" || inputtosearch.Text != "")
			{
				string from = MyUtil.ConvertVN(inputfromsearch.Text.ToLower().Replace(" ", ""));
				string to = MyUtil.ConvertVN(inputtosearch.Text.ToLower().Replace(" ", ""));
				foreach (BusItem bus in datagroup.Items)
				{
					string luotDi = MyUtil.ConvertVN(bus.RouteGo.ToLower().Replace(" ", ""));
					string luotVe = MyUtil.ConvertVN(bus.RouteReturn.ToLower().Replace(" ", ""));
					if ((luotDi.Contains(from) && luotDi.Contains(to)) || (luotVe.Contains(from) && luotVe.Contains(to)))
                    {
						listbus.Items.Add(bus);
					}
				}

				if (listbus.Items.Any())
				{
					Frame.Navigate(typeof(BusListResult), listbus);
				}
			}
		}
		private async void Button_StreetSearch_Click(object sender, RoutedEventArgs e)
		{
			BusGroup listbus = new BusGroup();
			if (inputstreetsearch.Text != "")
			{
				string search = MyUtil.ConvertVN(inputstreetsearch.Text.ToLower().Replace(" ", ""));
				foreach (BusItem bus in datagroup.Items)
				{
					if (MyUtil.ConvertVN(bus.RouteGo.ToLower().Replace(" ", "")).Contains(search) || MyUtil.ConvertVN(bus.RouteReturn.ToLower().Trim()).Contains(search))
					{
						listbus.Items.Add(bus);
					}
				}

				if (listbus.Items.Any())
				{
					Frame.Navigate(typeof(BusListResult), listbus);
				}
				else
				{
					var dialog = new MessageDialog("Không có tuyến nào đi qua đường này");
					await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => await dialog.ShowAsync());
				}
			}
		}
		private void seachrbusid_TextChanged(object sender, TextChangedEventArgs e)
		{
			datagroup2 = new BusGroup();
			if (seachrbusid.Text != "")
			{
				string search = MyUtil.ConvertVN(seachrbusid.Text.ToLower().Replace(" ", ""));

				foreach (BusItem bus in datagroup.Items)
				{
					string id = MyUtil.ConvertVN(bus.FleetID.ToLower().Replace(" ", ""));
					string name = MyUtil.ConvertVN(bus.Name.ToLower().Replace(" ", ""));
					if (id.Contains(search) || name.Contains(search))
					{
						datagroup2.Items.Add(bus);
					}
				}
				this.DefaultViewModel[FirstGroupName] = datagroup2;
			}
			else
			{
				this.DefaultViewModel[FirstGroupName] = datagroup;
			}
		}
		private async Task GetSampleDataAsync()
		{
			if (this._buses.Count != 0)
				return;

			ObservableCollection<BusItem> obi = new ObservableCollection<BusItem>();
			ObservableCollection<BusStop> obs = new ObservableCollection<BusStop>();

			for (int i = 1; i <= 74; i++)
			{
				List<Geopoint> RouteGoGeo = new List<Geopoint>();
				List<BusStop> RouteGoStations = new List<BusStop>();
				List<Geopoint> RouteReturnGeo = new List<Geopoint>();
				List<BusStop> RouteReturnStations = new List<BusStop>();
				List<BusNode> goNode = new List<BusNode>();
				List<BusNode> returnNode = new List<BusNode>();

				Uri dataUri = new Uri("ms-appx:///DataModel/" + i.ToString() + ".txt");
				StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(dataUri);
				string jsonText = await FileIO.ReadTextAsync(file);
				JsonObject jsonObject = JsonObject.Parse(jsonText)["dt"].GetObject();

				// Get Go
				JsonObject goObject = jsonObject["Go"].GetObject();
				JsonArray goGeoArray = goObject["Geo"].GetArray();
				foreach (JsonValue value in goGeoArray)
				{
					JsonObject goGeoObject = value.GetObject();

					double lng = goGeoObject["Lng"].GetNumber();
					double lat = goGeoObject["Lat"].GetNumber();
					RouteGoGeo.Add(new Geopoint(new BasicGeoposition { Latitude = lat, Longitude = lng }));
				}

				JsonArray goStationArray = goObject["Station"].GetArray();
				foreach (JsonValue value in goStationArray)
				{
					JsonObject goStationObject = value.GetObject();

					double lng = goStationObject["Geo"].GetObject()["Lng"].GetNumber();
					double lat = goStationObject["Geo"].GetObject()["Lat"].GetNumber();

					string code = "";
					try
					{
						code = goStationObject["ObjectID"].GetNumber().ToString();
						//code = goStationObject["Code"].GetString();
					}
					catch (Exception exc)
					{
						string errMsg = exc.Message;
					}

					BusStop bs = new BusStop(code,
												goStationObject["Name"].GetString(),
												goStationObject["FleetOver"].GetString(),
												new Geopoint(new BasicGeoposition { Latitude = lat, Longitude = lng }));
					RouteGoStations.Add(bs);

					BusNode bn = new BusNode(jsonObject["Code"].GetString(), code, null);
					goNode.Add(bn);	

					if (!obs.Any(a => a.Code == code))
					{
						bs.arrayNode.Add(bn);
						obs.Add(bs);
					}
					else
					{
						obs.Where(x => x.Code == code).FirstOrDefault().arrayNode.Add(bn);
					}
				
				}



				// Get Return
				JsonObject reObject = jsonObject["Re"].GetObject();
				JsonArray reGeoArray = reObject["Geo"].GetArray();
				foreach (JsonValue value in reGeoArray)
				{
					JsonObject reGeoObject = value.GetObject();

					double lng = reGeoObject["Lng"].GetNumber();
					double lat = reGeoObject["Lat"].GetNumber();
					RouteReturnGeo.Add(new Geopoint(new BasicGeoposition { Latitude = lat, Longitude = lng }));
				}

				JsonArray reStationArray = reObject["Station"].GetArray();
				foreach (JsonValue value in reStationArray)
				{
					JsonObject reStationObject = value.GetObject();

					double lng = reStationObject["Geo"].GetObject()["Lng"].GetNumber();
					double lat = reStationObject["Geo"].GetObject()["Lat"].GetNumber();

					string code = "";
					try
					{
						code = reStationObject["ObjectID"].GetNumber().ToString();
					}
					catch (Exception exc)
					{
						string errMsg = exc.Message;
					}

					BusStop bs = new BusStop(code,
												reStationObject["Name"].GetString(),
												reStationObject["FleetOver"].GetString(),
												new Geopoint(new BasicGeoposition { Latitude = lat, Longitude = lng }));
					RouteReturnStations.Add(bs);
					
					BusNode bn = new BusNode(jsonObject["Code"].GetString(), code, null);
					returnNode.Add(bn);

					if (!obs.Any(a => a.Code == code))
					{
						bs.arrayNode.Add(bn);
						obs.Add(bs);
					}
					else
					{
						obs.Where(x => x.Code == code).First().arrayNode.Add(bn);
					}
				}

				BusItem bus = new BusItem(jsonObject["FleetID"].GetNumber().ToString(),
											jsonObject["Code"].GetString(),
											jsonObject["Name"].GetString(),
											jsonObject["OperationsTime"].GetString(),
											jsonObject["Frequency"].GetString(),
											jsonObject["Cost"].GetString(),
											goObject["Route"].GetString(),
											RouteGoGeo,
											RouteGoStations,
											reObject["Route"].GetString(),
											RouteReturnGeo,
											RouteReturnStations);
				bus.goNode = goNode;
				bus.returnNode = returnNode;
				obi.Add(bus);
			}

			BusGroup bg = new BusGroup(obi, obs);
			this.Buses.Add(bg);

			foreach (BusItem bi in bg.Items)
			{
				for (int i = 0; i < bi.goNode.Count(); i++)
				{
					if (i < bi.goNode.Count()-1)
						bi.goNode[i].nextNode = bi.goNode[i + 1];
				}
				for (int i = 0; i < bi.returnNode.Count(); i++)
				{
					if (i < bi.returnNode.Count()-1)
						bi.returnNode[i].nextNode = bi.returnNode[i + 1];
				}
			}
		}
		/// <summary>
		/// The methods provided in this section are simply used to allow
		/// NavigationHelper to respond to the page's navigation methods.
		/// <para>
		/// Page specific logic should be placed in event handlers for the  
		/// <see cref="NavigationHelper.LoadState"/>
		/// and <see cref="NavigationHelper.SaveState"/>.
		/// The navigation parameter is available in the LoadState method 
		/// in addition to page state preserved during an earlier session.
		/// </para>
		/// </summary>
		/// <param name="e">Provides data for navigation methods and event
		/// handlers that cannot cancel the navigation request.</param>
		protected async override void OnNavigatedTo(NavigationEventArgs e)
		{
			this.navigationHelper.OnNavigatedTo(e);
			datagroup = e.Parameter as BusGroup;
			this.DefaultViewModel["AllBus"] = datagroup;

			// Get current location
			Geopoint myPoint;
			var locator = new Geolocator();
			if (locator.LocationStatus == PositionStatus.Disabled)
			{
				// Location is turned off
				var dialog = new MessageDialog("Location Service is turned off");
				await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, async () => await dialog.ShowAsync());
				return;
			}
			locator.DesiredAccuracyInMeters = 50;
			var position = await locator.GetGeopositionAsync();
			myPoint = position.Coordinate.Point;

		}