/// 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();
}
}
}