// Copyright 2010 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.android.stardroid.views; import com.google.android.stardroid.R; import com.google.android.stardroid.activities.DynamicStarMapActivity; import com.google.android.stardroid.control.AstronomerModel; import com.google.android.stardroid.provider.ephemeris.Planet; import com.google.android.stardroid.util.MiscUtil; import com.google.android.stardroid.util.TimeUtil; import android.app.DatePickerDialog; import android.app.DatePickerDialog.OnDateSetListener; import android.app.Dialog; import android.app.TimePickerDialog; import android.app.TimePickerDialog.OnTimeSetListener; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.DatePicker; import android.widget.Spinner; import android.widget.TextView; import android.widget.TimePicker; import android.widget.Toast; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * Implementation of the time travel dialog. * * @author Dominic Widdows * @author John Taylor */ public class TimeTravelDialog extends Dialog { private static final String TAG = MiscUtil.getTag(TimeTravelDialog.class); private Spinner popularDatesMenu; private TextView dateTimeReadout; private DynamicStarMapActivity parentActivity; private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z"); // This is the date we will apply to the controller when the user hits go. private Calendar calendar = Calendar.getInstance(); private AstronomerModel model; public TimeTravelDialog(final DynamicStarMapActivity parentActivity, final AstronomerModel model) { super(parentActivity); this.parentActivity = parentActivity; this.model = model; } @Override protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.time_dialog); // Assumes that the dialog's title should be the same as the menu option. setTitle(R.string.menu_time); // Capture our View elements dateTimeReadout = (TextView) findViewById(R.id.dateDisplay); // Capture and wire up the buttons Button changeDateButton = (Button) findViewById(R.id.pickDate); changeDateButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { createDatePicker().show(); } }); Button changeTimeButton = (Button) findViewById(R.id.pickTime); changeTimeButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { createTimePicker().show(); } }); Button goButton = (Button) findViewById(R.id.timeTravelGo); goButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { parentActivity.setTimeTravelMode(calendar.getTime()); hide(); } }); Button cancelButton = (Button) findViewById(R.id.timeTravelCancel); cancelButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { hide(); } }); popularDatesMenu = (Spinner) findViewById(R.id.popular_dates_spinner); ArrayAdapter<?> adapter = ArrayAdapter.createFromResource( this.getContext(), R.array.popular_date_examples, android.R.layout.simple_spinner_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); popularDatesMenu.setAdapter(adapter); popularDatesMenu.setSelection(1); popularDatesMenu.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { // The callback received when the user selects a menu item. @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { setPopularDate(popularDatesMenu.getSelectedItemPosition()); } @Override public void onNothingSelected(AdapterView<?> arg0) { // Do nothing in this case. } }); // Start by initializing ourselves to 'now'. Note that this is the value // the first time the dialog is shown. Thereafter it will remember the // last value set. calendar.setTime(new Date()); updateDisplay(); } private Dialog createTimePicker() { OnTimeSetListener timeSetListener = new TimePickerDialog.OnTimeSetListener() { public void onTimeSet(TimePicker view, int hour, int minute) { setTime(hour, minute); Log.d(TAG, "Setting time to: " + hour + ":" + minute); } }; return new TimePickerDialog(getContext(), timeSetListener, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), true) { }; } private Dialog createDatePicker() { OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { setDate(year, monthOfYear, dayOfMonth); Log.d(TAG, "Setting date to: " + year + "-" + monthOfYear + "-" + dayOfMonth); } }; return new DatePickerDialog(getContext(), dateSetListener, calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH)) { }; } /** * Sets the internal calendar of this dialog. Remember that months are zero * based. Current time is preserved. */ private void setDate(int year, int month, int day) { calendar.set(year, month, day); updateDisplay(); } /** * Sets the internal calendar of this dialog. Current date is preserved. */ private void setTime(int hour, int minute) { calendar.set(Calendar.HOUR_OF_DAY, hour); calendar.set(Calendar.MINUTE, minute); updateDisplay(); } /** * Sets the internal calendar of this dialog to the given date. */ private void setDate(Date date) { calendar.setTime(date); updateDisplay(); } private void updateDisplay() { Date date = calendar.getTime(); dateTimeReadout.setText(String.format(parentActivity.getString(R.string.now_visiting, dateFormat.format(date)))); } private void setToNextSunRiseOrSet(Planet.RiseSetIndicator indicator) { Calendar riseset = Planet.Sun.calcNextRiseSetTime(calendar, model.getLocation(), indicator); if (riseset == null) { Toast.makeText(this.getContext(), R.string.sun_wont_set_message, Toast.LENGTH_SHORT).show(); } else { Log.d(TAG, "Sun rise or set is at: " + TimeUtil.normalizeHours( riseset.get(Calendar.HOUR_OF_DAY)) + ":" + riseset.get(Calendar.MINUTE)); setDate(riseset.getTime()); } } /** * Associates time settings with the options in the popular dates menu. * It HAS to be kept in sync with res/values/arrays.xml. * * @param popularDateIndex The index into the popular dates array. */ private void setPopularDate(int popularDateIndex) { String s = (String) popularDatesMenu.getSelectedItem(); Log.d(TAG, "Popular date " + popularDatesMenu.getSelectedItemPosition() + " " + s); Calendar c = Calendar.getInstance(); c.setTime(model.getTime()); switch (popularDateIndex) { case 0: // Now calendar.setTime(new Date()); break; case 1: // Next sunset setToNextSunRiseOrSet(Planet.RiseSetIndicator.SET); break; case 2: // Next sunrise setToNextSunRiseOrSet(Planet.RiseSetIndicator.RISE); break; case 3: // Next full moon Date nextFullMoon = Planet.getNextFullMoon(calendar.getTime()); setDate(nextFullMoon); break; case 4: // Moon Landing 1969. setDate(new Date(-14182953622L)); break; case 5: // Solar Eclipse 1919. Hand-tuned to look OK, no exact moment. setDate(new Date(-1596619190000L)); break; default: Log.d(TAG, "Incorrect popular date index!"); } updateDisplay(); } }