/// Version 1.0.0 /// Last modified 24.5.2014 /// /// Copyright (C) 2014 Atte Söderlund /// /// Halyri-system is a prototype emergency call system. Its purpose is to /// demonstrate the use of the advanced capabilities available in the current /// generation smartphones in facilitating the emergency service dispatcher's /// capability to determine the nature of the emergency and to dispatch help. /// /// For more information, see the README file of this package. /// /// The MIT License (MIT) /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to /// deal in the Software without restriction, including without limitation the /// rights to use, copy, modify, merge, publish, distribute, sublicense, /// and/or sell copies of the Software, and to permit persons to whom the /// Software is furnished to do so, subject to the following conditions: /// /// The above copyright notice and this permission notice shall be included in /// all copies or substantial portions of the Software. /// /// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR /// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, /// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE /// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER /// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING /// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS /// IN THE SOFTWARE. /// using Hake_WPF.CallCenterReference; using Microsoft.Maps.MapControl.WPF; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Net; using Newtonsoft.Json.Linq; using Hake_WPF.Conversion; namespace Hake_WPF { /// Atte Söderlund /// /// The assigment listboxitem contains many properties like handlers, location, time, state, priority, /// pushpins, assigment info and street name. It sets the content and background depending on the state and the priority /// and if there is a location available. /// class Assignment : ListBoxItem, INotifyPropertyChanged { /// /// Is used to notify that a property has changed. /// public event PropertyChangedEventHandler PropertyChanged; private WebClient WebClientForLocationQuery; /// /// Notify that property is changed. This will update bindings. /// /// Info string private void NotifyPropertyChanged(String info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } private bool clientConnected; public bool ClientConnected { get { return clientConnected; } set { clientConnected = value; } } private String emergencyType; /// /// Sets and gets the emergency type. Emergency type can be any string that is short description about emergency. /// public String EmergencyType { get { return emergencyType; } set { emergencyType = value; } } private ObservableCollection textMessages = new ObservableCollection(); /// /// Textmessages in observablecollection. It is a collection of received and sent textmessages. /// public ObservableCollection TextMessages { get { return textMessages; } set { textMessages = value; } } private PersonalInformationDto personalInfo; /// /// Sets and gets the personal information as PersonalInformationDto that includes name, address and list /// of phone numbers all as strings. /// public PersonalInformationDto PersonalInfo { get { return personalInfo; } set { personalInfo = value; } } /// /// Not urgent and urgent enums. NotUrgent is 0 and Urgent is 1 as integers. /// public enum priorities { NotUrgent = 0, Urgent = 1 }; private priorities priority; /// /// Sets and gets priority of the assignment. When the value is set, it also sets background and the content. /// public priorities Priority { get { return priority; } set { priority = value; SetBackgroundColor(); SetContent(); } } private String guid = ""; /// /// Sets and gets the guid. It is used to identify the connection. /// public String Guid { get { return guid; } set { guid = value; } } private DateTime time; /// /// Sets and gets time. The time specifies when the assignment is taken in. When the time is setted, it also /// sets the background color and the content. /// public DateTime Time { get { return time; } set { time = value; SetBackgroundColor(); SetContent(); } } private bool noSound; /// /// Gets and sets NoSound. It specifies whether caller can speak or not. /// public bool NoSound { get { return noSound; } set { noSound = value; } } /// /// Enum of the connection states. New = 0,...,Hold=4. /// public enum States { New = 0, InProgress = 1, InTransfer = 2, Finalized = 3, Hold = 4 }; private States state; /// /// Sets the stage value and also takes care of the background color and the listboxitem content. /// Also if the state is finalized removes the pushpins. /// public States State { get { return state; } set { state = value; SetBackgroundColor(); SetContent(); if (value == States.Finalized) Pushpins.Clear(); } } private List stateBrushes = new List { new SolidColorBrush(new Color() { B = 48, R = 230, G = 48, A = 255 }), //New as RED new SolidColorBrush(new Color() { B = 235, R = 89, G = 63, A = 255 }), //InProgress as BLUE new SolidColorBrush(new Color() { B = 76, R = 252, G = 238, A = 255 }), // InTransfer as VIOLET new SolidColorBrush(new Color() { B = 131, R = 133, G = 132, A = 255 }), // Finalized as GREY new SolidColorBrush(new Color() { B = 79, R = 247, G = 205, A = 255 })}; //Hold as YELLOW /// /// Sets and gets IsHandler. It is used to determine currently active assignment. /// public bool IsHandler { get { return (bool)GetValue(IsHandlerProperty); } set { SetValue(IsHandlerProperty, value); } } /// /// DependencyProperty for ishandler. It is used to determine currently active assignment. /// public static readonly DependencyProperty IsHandlerProperty = DependencyProperty.Register("IsHandler", typeof(bool), typeof(MainWindow), new PropertyMetadata(false)); private LocationInformationDto location; /// /// Sets and gets the location as LocationInformationDto that contains the location, the accuracy in meters and the time. /// When this is setted, sets the content also. /// public LocationInformationDto Location { get { return location; } set { location = value; SetContent(); } } private double locationAccuracyMeters; /// /// Sets and gets the locationAccuracyMeters. It specifies how accurate the received GPS location is. /// public double LocationAccuracyMeters { get { return locationAccuracyMeters; } set { locationAccuracyMeters = value; } } private DateTimeOffset locationAcquisitionTime; /// /// Sets and gets LocationAcquisitionTime. It specifies the time when the location information is taken. /// public DateTimeOffset LocationAcquisitionTime { get { return locationAcquisitionTime; } set { locationAcquisitionTime = value; } } private ObservableCollection pushpins = new ObservableCollection(); /// /// Sets and gets Pushpins as a ObservableCollention. If the assignments state is finalized, /// it won't set the pushpins. Also adds the pushpins in the index 1 background to light green. /// public ObservableCollection Pushpins { get { return pushpins; } set { if (State == States.Finalized) return; try { pushpins = value; value[0].Background = Background; value[1].Background = Brushes.LightGreen; } catch(NullReferenceException) {} } } private String streetName; /// /// Sets and gets the streetname. When setted, also sets the content and invokes NotifyPropertyChanged delegate. /// public String StreetName { get { return streetName; } set { streetName = value; SetContent(); NotifyPropertyChanged("Found Street address from location"); } } private MobileDeviceInformationDto deviceInfo; /// /// Sets and gets the DeviceInfo. It contains information about the callers device. /// public MobileDeviceInformationDto DeviceInfo { get { return deviceInfo; } set { deviceInfo = value; } } /// /// The function initializes Assigment by setting state, priority, time, location, assimentinfo, background color and content. /// /// The assigment connection time /// The assigments priority from Assigment.Priorities /// The assigments state from Assigment.States /// The assigments location public Assignment(String guid, DateTime time, priorities priority, States state, LocationInformationDto location) { Guid = guid; State = state; Priority = priority; Time = time; Location = location; getStreetNameFromLocationAsync(); } /// /// The constructor without location. /// /// The assigment connection time /// The assigments priority from Assigment.Priorities /// The assigments state from Assigment.States public Assignment(String guid, DateTime time, priorities priority, States state) { Guid = guid; State = state; Priority = priority; Time = time; SetBackgroundColor(); } /// /// Sets different content for listboxitem depending on what information is already set. /// For location uses format 00.0000 that shows 4 decimals of latitude and longitude. /// Also converts other text to right form like state and priority. /// private void SetContent() { PriorityConverter priorityConverter = new PriorityConverter(); StateConverter stateConverter = new StateConverter(); Content = Time.ToShortTimeString() + " " + StreetName + ((Location != null)? "\n" + Location.Longitude.ToString("00.0000") + ", " + Location.Latitude.ToString("00.0000") : "") + "\n" + stateConverter.Convert(State,typeof(String), null,System.Globalization.CultureInfo.CurrentCulture) + " | " + priorityConverter.Convert(Priority, typeof(String), null, System.Globalization.CultureInfo.CurrentCulture); } /// /// Depending on state and priority, sets backgroundcolor for listboxitem and for pushpin. /// private void SetBackgroundColor() { Background = stateBrushes[(int)State]; if (Priority == priorities.NotUrgent && State == States.New) Background = new SolidColorBrush(new Color() { A = 255, R = 189, G = 90, B = 250 }); if (Pushpins.Count > 0) Pushpins[0].Background = this.Background; } /// Niko Mononen /// /// Updates street name according to location with Bing Maps API /// Function makes asynchronous call to Bing Maps APi rest service which returns /// information about given location /// private void getStreetNameFromLocationAsync() { WebClientForLocationQuery = new WebClient(); try { var url = String.Format(System.Globalization.CultureInfo.GetCultureInfo("en-US"), "http://dev.virtualearth.net/REST/v1/Locations/{0},{1}?key={2}", Location.Latitude, Location.Longitude, Properties.Settings.Default.BingApiKey ); WebClientForLocationQuery.Encoding = System.Text.Encoding.UTF8; WebClientForLocationQuery.DownloadStringAsync(new Uri(url)); WebClientForLocationQuery.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadStringCallback); } catch (Exception ex) { Console.WriteLine("Error during WebClient request:" + ex.ToString()); WebClientForLocationQuery.Dispose(); } } /// Niko Mononen /// /// Callback function for Webclient Download completed event. /// This function sets Streetname according to location. /// /// Callback sender /// Download completed event arguments private void DownloadStringCallback(Object sender, DownloadStringCompletedEventArgs e) { if (!e.Cancelled && e.Error == null) { try { JObject jObject = JObject.Parse(e.Result); StreetName = (String)jObject["resourceSets"].First()["resources"].Last()["name"]; } catch (Exception ex) { Console.WriteLine("Error while parsing result" + ex.ToString()); } } WebClientForLocationQuery.Dispose(); } } }