Click here to Skip to main content
15,891,033 members
Articles / Mobile Apps / Windows Mobile

PlanetFinder for Windows Mobile

Rate me:
Please Sign up or sign in to vote.
4.26/5 (8 votes)
17 Dec 2008GPL37 min read 29.4K   552   30  
PlanetFinder application for Windows Mobile Smartphones
/*

Copyright (c) 2000 Benjamin Crowell,
              2008 Kostas Giannakakis. All rights reserved.

About the GPL License
	This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Globalization;

using Microsoft.WindowsMobile.Samples.Location;
using Microsoft.WindowsCE.Forms;

namespace PlanetFinder
{
    public partial class Form1 : Form
    {
        private PlanetFinderEngine planetFinder;

        private int width = GetSystemMetrics(SM_CXSCREEN);
        private int height = GetSystemMetrics(SM_CYSCREEN);

        private DateTime dateTime;

        private TimeSettings timeSettings;
        private PositionSettings positionFinder;
        private Preferences preferences;

        private CultureInfo cultureInfo = new CultureInfo("en-US");

        private string APP_KEY_NAME = @"HKEY_LOCAL_MACHINE\SOFTWARE\SullenArt\PlanetFinder";

        private Timer autoUpdateTimer;

        private Timer suspendTimer;

        private bool suspendMode;

        #region Gps Code

        private Gps gps;
        private GpsDeviceState gpsDeviceState = null;
        private GpsPosition gpsPosition = null;
        private System.EventHandler gpsUpdateDataHandler;

        private int gpsEventCounter;
        private bool useGps = false;
        private bool gpsValid = false;

        private void GpsInit()
        {
            gps = new Gps();            

            gpsUpdateDataHandler = new System.EventHandler(GpsUpdateData);
            gps.DeviceStateChanged += 
                new DeviceStateChangedEventHandler(gps_DeviceStateChanged);
            gps.LocationChanged += 
                new LocationChangedEventHandler(gps_LocationChanged);
        }

        private void GpsStart()
        {
            gpsEventCounter = 0;
            gps.Open();
        }

        private void GpsStop()
        {
            if (gps.Opened)
            {
                gps.Close();
                gpsEventCounter = 0;
                gpsValid = false;
                gpsPosition = null;
                gpsDeviceState = null;
            }
        }

        protected void gps_LocationChanged(object sender,
                                    LocationChangedEventArgs args)
        {
            gpsPosition = args.Position;
            GpsStateOrPositionChanged();
        }

        protected void gps_DeviceStateChanged(object sender,
                                    DeviceStateChangedEventArgs args)
        {
            gpsDeviceState = args.DeviceState;
            GpsStateOrPositionChanged();
        }

        private void GpsStateOrPositionChanged()
        {
            bool prevState = gpsValid;

            // Calculate Gps Valid
            gpsValid = gpsPosition != null &&
                       gpsDeviceState != null && 
                       gpsPosition.SatellitesInViewCountValid &&
                       gpsPosition.SatellitesInViewCount > 1 &&
                       gpsPosition.TimeValid &&
                       gpsPosition.LongitudeValid &&
                       gpsPosition.LatitudeValid &&
                       gpsDeviceState.DeviceState == GpsServiceState.On;

            if (gpsValid)
            {
                positionFinder.Longitude = gpsPosition.Longitude;
                positionFinder.Latitude = gpsPosition.Latitude;
                positionFinder.PositionName = "";
            }
            
            if (prevState != gpsValid || 
                (!gpsValid && gpsEventCounter == 0))
            {
                Invoke(gpsUpdateDataHandler);
            }
            gpsEventCounter++;
            if (gpsEventCounter == 10)
            {
                gpsEventCounter = 0;
            }
        }

        void GpsUpdateData(object sender, System.EventArgs args)
        {
            if (gps.Opened)
            {
                gpsPanel.Visible = !gpsValid;
                if (!gpsValid && gpsPosition != null)
                {
                    labelLatitude.Text = "Latitude: ";
                    if (gpsPosition.LatitudeValid)
                    {
                        labelLatitude.Text +=
                            String.Format(cultureInfo, "{0:0.00}",
                                          gpsPosition.Latitude);
                    }
                    labelLongitude.Text = "Latitude: ";
                    if (gpsPosition.LongitudeValid)
                    {
                        labelLongitude.Text +=
                            String.Format(cultureInfo, "{0:0.00}",
                                          gpsPosition.Longitude);
                    }
                    labelSatellites.Text = "Satellites: ";
                    if (gpsPosition.SatelliteCountValid)
                    {
                        labelSatellites.Text += String.Format("{0}",
                                                gpsPosition.SatelliteCount);
                    }
                    labelTime.Text = "Time: ";
                    if (gpsPosition.TimeValid)
                    {
                        labelTime.Text = gpsPosition.Time.ToLongTimeString() + " " +
                                         gpsPosition.Time.ToShortDateString();
                    }
                }
            }
            else
            {
                gpsPanel.Visible = false;
            }
            UpdateSky();
        }

        #endregion

        public Form1()
        {
            InitializeComponent();

            InputModeEditor.SetInputMode(latitudeTextBox, InputMode.Numeric);
            InputModeEditor.SetInputMode(longitudeTextBox, InputMode.Numeric);

            GpsInit();

            preferences = new Preferences(APP_KEY_NAME);
            timeSettings = new TimeSettings(APP_KEY_NAME);

            positionFinder = new PositionSettings(APP_KEY_NAME, 
                                                timeSettings.Timezone);

            dateTime = DateTime.Now;

            planetFinder = new PlanetFinderEngine();
            UpdateSky();

            dateTimePicker1.Format = DateTimePickerFormat.Custom;
            dateTimePicker1.CustomFormat = "HH:mm, dd MM yyyy";
            controlPanel.Visible = false;
            UpdatePanel();

            autoUpdateTimer = new Timer();
            autoUpdateTimer.Tick += new EventHandler(autoUpdateTimer_Tick);
            autoUpdateTimer.Interval = 60000;


            suspendMode = false;
            suspendTimer = new Timer();
            suspendTimer.Tick += new EventHandler(suspendTimer_Tick);
            suspendTimer.Interval = 10000;
        }

        void AutoTimerEnable(bool autoUpdate)
        {
            dateTimePicker1.Enabled = !autoUpdate;
            if (autoUpdate && !autoUpdateTimer.Enabled)
            {
                autoUpdateTimer.Enabled = true;
            }
            else if (!autoUpdate && autoUpdateTimer.Enabled)
            {
                autoUpdateTimer.Enabled = false;
            }
        }

        void RefreshTime()
        {
            if (preferences.AutoUpdate)
            {
                dateTime = DateTime.Now;
                dateTimePicker1.Value = dateTime;
                UpdatePanel();
                UpdateSky();
            }
        }

        void autoUpdateTimer_Tick(object sender, EventArgs e)
        {
            if (!useGps)
            {
                RefreshTime();
            }
            else 
            {
                if (gpsValid)
                {
                    dateTime = gpsPosition.Time;
                    dateTime = DateTime.Now;
                    dateTimePicker1.Value = dateTime;
                    UpdatePanel();
                    UpdateSky();
                }
            }
        }

        private void UpdatePanel()
        {
            if (positionFinder.PositionName != null &&
                positionFinder.PositionName.Length > 0)
            {
                Text = "PlanetFinder: " + positionFinder.PositionName;
            }
            else if (!useGps)
            {
                Text = "PlanetFinder";
            }

            longitudeTextBox.Text = String.Format(cultureInfo,
                                            "{0:0.0}", positionFinder.Longitude);
            latitudeTextBox.Text = String.Format(cultureInfo,
                                            "{0:0.0}", positionFinder.Latitude);
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics graph = e.Graphics;

            int size = width > height ? height : width;

            planetFinder.InitGraphics(graph, size, size);
            planetFinder.updateSky(0);

            if (planetFinder.NightTime)
            {
                // Adjust background color
                this.BackColor = Color.DarkGray;
            }
            else
            {
                this.BackColor = Color.White;
            }
        }

        private void menuItemExit_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void menuItemPanel_Click(object sender, EventArgs e)
        {
            if (controlPanel.Visible)
            {                
                controlPanel.Visible = false;
            }
            else
            {
                if (!useGps || gpsValid)
                {
                    UpdatePanel();
                    controlPanel.Visible = true;
                    latitudeTextBox.Focus();
                }
            }
        }

        private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
        {
            dateTime = dateTimePicker1.Value;
            UpdateSky();
        }

        private void textBoxLatitude_LostFocus(object sender, EventArgs e)
        {
            if (controlPanel.Visible)
            {
                try
                {
                    double val = Double.Parse(latitudeTextBox.Text, cultureInfo);
                    if (val != positionFinder.Latitude)
                    {
                        positionFinder.Latitude = val;
                        positionFinder.PositionName = "";
                        Text = "PlanetFinder";
                        UpdateSky();
                    }
                }
                catch (Exception)
                {
                }
            }
        }

        private void textBoxLongitude_LostFocus(object sender, EventArgs e)
        {
            if (controlPanel.Visible)
            {
                try
                {
                    double val = Double.Parse(longitudeTextBox.Text, cultureInfo);
                    if (val != positionFinder.Longitude)
                    {
                        positionFinder.Longitude = val;
                        positionFinder.PositionName = "";
                        Text = "PlanetFinder";
                        UpdateSky();
                    }
                }
                catch (Exception)
                {
                }
            }
        }

        private void checkBoxNakedEyePlanetsOnly_CheckStateChanged(object sender, EventArgs e)
        {
            UpdateSky();
        }

        private void UpdateSky()
        {
            if (!useGps)
            {
                planetFinder.init(timeSettings.UTCOffset, positionFinder.Longitude,
                                  positionFinder.Latitude, dateTime,
                                  preferences.NakedEyePlanetsOnly);
            }
            else if (gpsValid)
            {
                planetFinder.init(0, gpsPosition.Longitude,
                                  gpsPosition.Latitude, gpsPosition.Time,
                                  preferences.NakedEyePlanetsOnly);
            }
            Invalidate();
        }

        private void menuItemPosition_Click(object sender, EventArgs e)
        {
            controlPanel.Visible = false;
            PositionForm form = new PositionForm(timeSettings.Timezone);
            form.PositionName = positionFinder.PositionName;
            if (form.ShowDialog() == DialogResult.OK)
            {
                positionFinder.Longitude = form.Longitude;
                positionFinder.Latitude = form.Latitude;
                positionFinder.PositionName = form.PositionName;
                UpdateSky();
                UpdatePanel();
            }
        }

        private void menuItemTime_Click(object sender, EventArgs e)
        {
            controlPanel.Visible = false;
            TimeForm form = new TimeForm();
            form.Auto = timeSettings.Auto;
            form.Timezone = timeSettings.Timezone;
            form.IsDaylightSavings = timeSettings.IsDaylightSavings;
            if (form.ShowDialog() == DialogResult.OK)
            {
                double previousTimezone = timeSettings.Timezone;
                timeSettings.Auto = form.Auto;
                if (!form.Auto)
                {
                    timeSettings.Timezone = form.Timezone;
                }
                if (previousTimezone != timeSettings.Timezone)
                {
                    positionFinder.ChangeTimezone(timeSettings.Timezone);
                    MessageBox.Show("Timezone modified - Your position has changed!",
                                    "PlanetFinder",
                                    MessageBoxButtons.OK,
                                    MessageBoxIcon.Asterisk, 
                                    MessageBoxDefaultButton.Button1);
                    UpdatePanel();
                }
                UpdateSky();
            }
        }

        private void menuItemPreferences_Click(object sender, EventArgs e)
        {
            PreferencesForm form = new PreferencesForm(preferences.AutoUpdate,
                                            preferences.NakedEyePlanetsOnly,
                                            preferences.BacklightOff);

            if (form.ShowDialog() == DialogResult.OK)
            {
                preferences.AutoUpdate = form.AutoUpdate;
                preferences.NakedEyePlanetsOnly = form.NakedEyePlanetsOnly;
                preferences.BacklightOff = form.BacklightOff;
                if (!useGps)
                {
                    AutoTimerEnable(preferences.AutoUpdate);
                    UpdateSky();
                }
            }
        }

        private void menuItemGps_Click(object sender, EventArgs e)
        {
            if (useGps)
            {
                GpsStop();
                gpsPanel.Visible = false;
                useGps = false;
                menuItemGps.Checked = false;
                menuItemSettings.Enabled = true;
                longitudeTextBox.Enabled = true;
                latitudeTextBox.Enabled = true;                
                dateTime = DateTime.Now;
                dateTimePicker1.Value = dateTime;                
                AutoTimerEnable(preferences.AutoUpdate);
                UpdatePanel();
                UpdateSky();
            }
            else
            {
                useGps = true;
                gpsValid = false;
                menuItemGps.Checked = true;
                menuItemSettings.Enabled = false;
                longitudeTextBox.Enabled = false;
                latitudeTextBox.Enabled = false;
                Text = "PlanetFinder: Gps";
                AutoTimerEnable(true);

                gpsPanel.Visible = true;
                GpsStart();
            }
        }

        private void Form1_Closed(object sender, EventArgs e)
        {
            if (useGps)
            {
                GpsStop();
            }
            if (preferences.BacklightOff)
            {
                Backlight.Enable(true);
            }
            CityList.GetInstance().Save();            
            positionFinder.Close();
            timeSettings.Close();
            preferences.Close();
        }

        void suspendTimer_Tick(object sender, EventArgs e)
        {
            suspendTimer.Enabled = false;
            autoUpdateTimer.Enabled = false;
            if (useGps)
            {
                GpsStop();
            }
            if (preferences.BacklightOff)
            {
                Backlight.Enable(true);
            }
            suspendMode = true;
        }

        protected override void OnDeactivate(EventArgs e)
        {
            // Start the suspend Timer - release resources when the timer expires
            suspendTimer.Enabled = true;
        }

        protected override void OnActivated(EventArgs e)
        {
            suspendTimer.Enabled = false;

            if (suspendMode)
            {
                if (useGps)
                {
                    AutoTimerEnable(true);
                    GpsStart();
                }
                else
                {
                    AutoTimerEnable(preferences.AutoUpdate);
                    RefreshTime();
                }
                Backlight.Enable(!preferences.BacklightOff);                
                
                suspendMode = false;
            }
        }

        #region Dll_imports

        [DllImport("coredll.dll", EntryPoint = ("GetSystemMetrics"))]
        public static extern int GetSystemMetrics(int nIndex);

        private const int SM_CXSCREEN = 0;
        private const int SM_CYSCREEN = 1;

        #endregion

    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer (Senior) Self employed
Greece Greece
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions