You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by pu...@apache.org on 2012/02/22 09:15:23 UTC

[18/29] stage 2 - fix errors

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/4789ce6d/framework/Cordova/Commands/Compass.cs
----------------------------------------------------------------------
diff --git a/framework/Cordova/Commands/Compass.cs b/framework/Cordova/Commands/Compass.cs
new file mode 100644
index 0000000..f0dd842
--- /dev/null
+++ b/framework/Cordova/Commands/Compass.cs
@@ -0,0 +1,343 @@
+/*  
+	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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using DeviceCompass = Microsoft.Devices.Sensors.Compass;
+using System.Windows.Threading;
+using System.Runtime.Serialization;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.Threading;
+using Microsoft.Devices.Sensors;
+
+namespace WP7GapClassLib.Cordova.Commands
+{
+
+    public class Compass : BaseCommand
+    {
+        #region Static members
+
+        /// <summary>
+        /// Status of listener
+        /// </summary>
+        private static int currentStatus;
+
+        /// <summary>
+        /// Id for get getCompass method
+        /// </summary>
+        private static string getCompassId = "getCompassId";
+
+        /// <summary>
+        /// Compass
+        /// </summary>
+        private static DeviceCompass compass = new DeviceCompass();
+
+        /// <summary>
+        /// Listeners for callbacks
+        /// </summary>
+        private static Dictionary<string, Compass> watchers = new Dictionary<string, Compass>();
+
+        #endregion
+
+        #region Status codes
+
+        public const int Stopped = 0;
+        public const int Starting = 1;
+        public const int Running = 2;
+        public const int ErrorFailedToStart = 4;
+        public const int Not_Supported = 20;
+
+        /*
+         *   // Capture error codes
+            CompassError.COMPASS_INTERNAL_ERR = 0;
+            CompassError.COMPASS_NOT_SUPPORTED = 20;
+         * */
+
+        #endregion
+
+        #region CompassOptions class
+        /// <summary>
+        /// Represents Accelerometer options.
+        /// </summary>
+        [DataContract]
+        public class CompassOptions
+        {
+            /// <summary>
+            /// How often to retrieve the Acceleration in milliseconds
+            /// </summary>
+            [DataMember(IsRequired = false, Name = "frequency")]
+            public int Frequency { get; set; }
+
+            /// <summary>
+            /// The change in degrees required to initiate a watchHeadingFilter success callback.
+            /// </summary>
+            [DataMember(IsRequired = false, Name = "filter")]
+            public int Filter { get; set; }
+
+            /// <summary>
+            /// Watcher id
+            /// </summary>
+            [DataMember(IsRequired = false, Name = "id")]
+            public string Id { get; set; }
+
+        }
+        #endregion
+
+
+        /// <summary>
+        /// Time the value was last changed
+        /// </summary>
+        //private DateTime lastValueChangedTime;
+
+        /// <summary>
+        /// Accelerometer options
+        /// </summary>
+        private CompassOptions compassOptions;
+
+        //bool isDataValid;
+
+        //bool calibrating = false;
+
+        public Compass()
+        {
+
+        }
+
+        /// <summary>
+        /// Formats current coordinates into JSON format
+        /// </summary>
+        /// <returns>Coordinates in JSON format</returns>
+        private string GetHeadingFormatted(CompassReading reading)
+        {
+            string result = String.Format("\"magneticHeading\":{0},\"headingAccuracy\":{1},\"trueHeading\":{2},\"timestamp\":{3}",
+                            reading.MagneticHeading.ToString("0.0", CultureInfo.InvariantCulture),
+                            reading.HeadingAccuracy.ToString("0.0", CultureInfo.InvariantCulture),
+                            reading.TrueHeading.ToString("0.0", CultureInfo.InvariantCulture),
+                            reading.Timestamp.UtcTicks.ToString());
+            result = "{" + result + "}";
+            return result;
+        }
+
+        public void getHeading(string options)
+        {
+            if (!DeviceCompass.IsSupported)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
+            }
+            else
+            {
+                if (compass == null)
+                {
+                    // Instantiate the compass.
+                    compass = new DeviceCompass();
+                    compass.TimeBetweenUpdates = TimeSpan.FromMilliseconds(40);
+                    compass.CurrentValueChanged += new EventHandler<Microsoft.Devices.Sensors.SensorReadingEventArgs<Microsoft.Devices.Sensors.CompassReading>>(compass_CurrentValueChanged);
+                    compass.Calibrate += new EventHandler<Microsoft.Devices.Sensors.CalibrationEventArgs>(compass_Calibrate);
+                }
+                
+                
+                compass.Start();
+            }
+
+            try
+            {
+                if (currentStatus != Running)
+                {
+                    int status = this.start();
+                    if (status == ErrorFailedToStart)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+                        return;
+                    }
+
+                    long timeout = 2000;
+                    while ((currentStatus == Starting) && (timeout > 0))
+                    {
+                        timeout = timeout - 100;
+                        Thread.Sleep(100);
+                    }
+
+                    if (currentStatus != Running)
+                    {
+                        DispatchCommandResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, ErrorFailedToStart));
+                        return;
+                    }
+                }
+                lock (compass)
+                {
+                    if (watchers.ContainsKey(getCompassId))
+                    {
+                        compass.CurrentValueChanged -= watchers[getCompassId].compass_CurrentValueChanged;
+                        watchers.Remove(getCompassId);
+                    }
+                    DispatchCommandResult(new PluginResult(PluginResult.Status.OK, GetHeadingFormatted(compass.CurrentValue)));
+                }
+            }
+            catch (UnauthorizedAccessException)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION, ErrorFailedToStart));
+            }
+            catch (Exception)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
+            }
+        }
+
+        /// <summary>
+        /// Starts listening for compass sensor
+        /// </summary>
+        /// <returns>status of listener</returns>
+        private int start()
+        {
+
+            if ((currentStatus == Running) || (currentStatus == Starting))
+            {
+                return currentStatus;
+            }
+            try
+            {
+                lock (compass)
+                {
+                    watchers.Add(getCompassId, this);
+                    compass.CurrentValueChanged += watchers[getCompassId].compass_CurrentValueChanged;
+                    compass.Start();
+                    this.SetStatus(Starting);
+                }
+            }
+            catch (Exception)
+            {
+                this.SetStatus(ErrorFailedToStart);
+            }
+            return currentStatus;
+        }
+
+        public void startWatch(string options)
+        {
+            if (!DeviceCompass.IsSupported)
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, Not_Supported));
+            }
+
+            try
+            {
+                compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
+            }
+            catch (Exception ex)
+            {
+                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+                return;
+            }
+
+            if (string.IsNullOrEmpty(compassOptions.Id))
+            {
+                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                return;
+            }
+
+            try
+            {
+                lock (compass)
+                {
+                    watchers.Add(compassOptions.Id, this);
+                    compass.CurrentValueChanged += watchers[compassOptions.Id].compass_CurrentValueChanged;
+                    compass.Start();
+                    this.SetStatus(Starting);
+                }
+            }
+            catch (Exception)
+            {
+                this.DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ErrorFailedToStart));
+                return;
+            }
+        }
+
+        public void stopWatch(string options)
+        {
+            try
+            {
+                compassOptions = JSON.JsonHelper.Deserialize<CompassOptions>(options);
+            }
+            catch (Exception ex)
+            {
+                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION, ex.Message));
+                return;
+            }
+
+            if (string.IsNullOrEmpty(compassOptions.Id))
+            {
+                this.DispatchCommandResult(new PluginResult(PluginResult.Status.JSON_EXCEPTION));
+                return;
+            }
+
+            if (currentStatus != Stopped)
+            {
+                lock (compass)
+                {
+                    Compass watcher = watchers[compassOptions.Id];
+                    compass.CurrentValueChanged -= watcher.compass_CurrentValueChanged;
+                    watchers.Remove(compassOptions.Id);
+                    watcher.Dispose();
+                }
+            }
+            this.SetStatus(Stopped);
+
+            this.DispatchCommandResult();
+        }
+
+        void compass_Calibrate(object sender, Microsoft.Devices.Sensors.CalibrationEventArgs e)
+        {
+            //throw new NotImplementedException();
+            // TODO: pass calibration error to JS
+        }
+
+        void compass_CurrentValueChanged(object sender, Microsoft.Devices.Sensors.SensorReadingEventArgs<CompassReading> e)
+        {
+            if (compass.IsDataValid)
+            {
+                // trueHeading :: The heading in degrees from 0 - 359.99 at a single moment in time.
+                //  magneticHeading:: The heading relative to the geographic North Pole in degrees 0 - 359.99 at a single moment in time. 
+                //  A negative value indicates that the true heading could not be determined.
+                // headingAccuracy :: The deviation in degrees between the reported heading and the true heading.
+                //rawMagnetometerReading = e.SensorReading.MagnetometerReading;
+
+                //Debug.WriteLine("Compass Result :: " + GetHeadingFormatted(e.SensorReading));
+
+                PluginResult result = new PluginResult(PluginResult.Status.OK,GetHeadingFormatted(e.SensorReading));
+                result.KeepCallback = true;
+
+                DispatchCommandResult(result);
+            }
+        }
+
+        /// <summary>
+        /// Sets current status
+        /// </summary>
+        /// <param name="status">current status</param>
+        private void SetStatus(int status)
+        {
+            currentStatus = status;
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/4789ce6d/framework/Cordova/Commands/Connection.cs
----------------------------------------------------------------------
diff --git a/framework/Cordova/Commands/Connection.cs b/framework/Cordova/Commands/Connection.cs
new file mode 100644
index 0000000..635e4e1
--- /dev/null
+++ b/framework/Cordova/Commands/Connection.cs
@@ -0,0 +1,89 @@
+/*  
+	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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Net.NetworkInformation;
+
+namespace WP7GapClassLib.Cordova.Commands
+{
+
+    // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation(v=VS.92).aspx
+    // http://msdn.microsoft.com/en-us/library/microsoft.phone.net.networkinformation.devicenetworkinformation(v=VS.92).aspx
+
+    public class Connection : BaseCommand
+    {
+        const string UNKNOWN = "unknown";
+        const string ETHERNET = "ethernet";
+        const string WIFI = "wifi";
+        const string CELL_2G = "2g";
+        const string CELL_3G = "3g";
+        const string CELL_4G = "4g";
+        const string NONE = "none";
+        const string CELL = "cellular";
+
+
+        public void getConnectionInfo(string empty)
+        {
+
+            //DeviceNetworkInformation.NetworkAvailabilityChanged += new EventHandler<NetworkNotificationEventArgs>(DeviceNetworkInformation_NetworkAvailabilityChanged);
+
+            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, checkConnectionType()));
+        }
+
+        //void DeviceNetworkInformation_NetworkAvailabilityChanged(object sender, NetworkNotificationEventArgs e)
+        //{
+        //    throw new NotImplementedException();
+        //}
+
+        private string checkConnectionType()
+        {
+
+            if (DeviceNetworkInformation.IsNetworkAvailable)
+            {
+                if (DeviceNetworkInformation.IsWiFiEnabled)
+                {
+                    return WIFI;
+                }
+                else
+                {
+                    if (DeviceNetworkInformation.IsCellularDataEnabled)
+                    {
+                        // WP7 doesn't let us determine which type of cell data network
+                        // DeviceNetworkInformation.CellularMobileOperator
+                        return CELL;
+                    }
+                    else
+                    {
+                        return UNKNOWN;
+                    }
+                }
+            }
+            else
+            {
+                return NONE;
+            }
+        }
+
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/4789ce6d/framework/Cordova/Commands/Contacts.cs
----------------------------------------------------------------------
diff --git a/framework/Cordova/Commands/Contacts.cs b/framework/Cordova/Commands/Contacts.cs
new file mode 100644
index 0000000..575233d
--- /dev/null
+++ b/framework/Cordova/Commands/Contacts.cs
@@ -0,0 +1,527 @@
+/*  
+	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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Tasks;
+using Microsoft.Phone.UserData;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+using DeviceContacts = Microsoft.Phone.UserData.Contacts;
+using System.Diagnostics;
+using System.Linq;
+
+
+namespace WP7GapClassLib.Cordova.Commands
+{
+    [DataContract]
+    public class SearchOptions
+    {
+        [DataMember]
+        public string filter { get; set; }
+        [DataMember]
+        public bool multiple { get; set; }
+    }
+
+    [DataContract]
+    public class ContactSearchParams
+    {
+        [DataMember]
+        public string[] fields { get; set; }
+        [DataMember]
+        public SearchOptions options { get; set; }
+    }
+
+    [DataContract]
+    public class JSONContactAddress
+    {
+        [DataMember]
+        public string formatted { get; set; }
+        [DataMember]
+        public string type { get; set; }
+        [DataMember]
+        public string streetAddress { get; set; }
+        [DataMember]
+        public string locality { get; set; }
+        [DataMember]
+        public string region { get; set; }
+        [DataMember]
+        public string postalCode { get; set; }
+        [DataMember]
+        public string country { get; set; }
+        [DataMember]
+        public bool pref { get; set; }
+    }
+
+    [DataContract]
+    public class JSONContactName
+    {
+        [DataMember]
+        public string formatted { get; set; }
+        [DataMember]
+        public string familyName { get; set; }
+        [DataMember]
+        public string givenName { get; set; }
+        [DataMember]
+        public string middleName { get; set; }
+        [DataMember]
+        public string honorificPrefix { get; set; }
+        [DataMember]
+        public string honorificSuffix { get; set; }
+    }
+
+    [DataContract]
+    public class JSONContactField
+    {
+        [DataMember]
+        public string type { get; set; }
+        [DataMember]
+        public string value { get; set; }
+        [DataMember]
+        public bool pref { get; set; }
+    }
+
+    [DataContract]
+    public class JSONContactOrganization
+    {
+        [DataMember]
+        public string type { get; set; }
+        [DataMember]
+        public string name { get; set; }
+        [DataMember]
+        public bool pref { get; set; }
+        [DataMember]
+        public string department { get; set; }
+        [DataMember]
+        public string title { get; set; }
+    }
+
+    [DataContract]
+    public class JSONContact
+    {
+        [DataMember]
+        public string id { get; set; }
+        [DataMember]
+        public string rawId { get; set; }
+        [DataMember]
+        public string displayName { get; set; }
+        [DataMember]
+        public string nickname { get; set; }
+        [DataMember]
+        public string note { get; set; }
+
+        [DataMember]
+        public JSONContactName name { get; set; }
+
+        [DataMember]
+        public JSONContactField[] emails { get; set; }
+
+        [DataMember]
+        public JSONContactField[] phoneNumbers { get; set; }
+
+        [DataMember]
+        public JSONContactField[] ims { get; set; }
+
+        [DataMember]
+        public JSONContactField[] photos { get; set; }
+
+        [DataMember]
+        public JSONContactField[] categories { get; set; }
+
+        [DataMember]
+        public JSONContactField[] urls { get; set; }
+
+        [DataMember]
+        public JSONContactOrganization[] organizations { get; set; }
+
+        [DataMember]
+        public JSONContactAddress[] addresses { get; set; }
+    }
+
+    public class Contacts : BaseCommand
+    {
+
+        public Contacts()
+        {
+
+        }
+
+        private void saveContactTask_Completed(object sender, SaveContactResult e)
+        {
+            switch (e.TaskResult)
+            {
+                case TaskResult.OK:
+                    // successful save
+                    MessageBoxResult res = MessageBox.Show("contact saved", "Alert", MessageBoxButton.OK);
+                    break;
+                case TaskResult.Cancel:
+                    // user cancelled
+                    break;
+                case TaskResult.None:
+                    // no info about result is available
+                    break;
+            }
+        }
+
+        // refer here for contact properties we can access: http://msdn.microsoft.com/en-us/library/microsoft.phone.tasks.savecontacttask_members%28v=VS.92%29.aspx
+        public void save(string jsonContact)
+        {
+
+            JSONContact contact = JSON.JsonHelper.Deserialize<JSONContact>(jsonContact);
+
+            SaveContactTask contactTask = new SaveContactTask();
+
+            if (contact.nickname != null)
+            {
+                contactTask.Nickname = contact.nickname;
+            }
+            if (contact.urls != null && contact.urls.Length > 0)
+            {
+                contactTask.Website = contact.urls[0].value;
+            }
+            if (contact.note != null)
+            {
+                contactTask.Notes = contact.note;
+            }
+
+            #region contact.name
+            if (contact.name != null)
+            {
+                if (contact.name.givenName != null)
+                    contactTask.FirstName = contact.name.givenName;
+                if (contact.name.familyName != null)
+                    contactTask.LastName = contact.name.familyName;
+                if (contact.name.middleName != null)
+                    contactTask.MiddleName = contact.name.middleName;
+                if (contact.name.honorificSuffix != null)
+                    contactTask.Suffix = contact.name.honorificSuffix;
+                if (contact.name.honorificPrefix != null)
+                    contactTask.Title = contact.name.honorificPrefix;
+            }
+            #endregion
+
+            #region contact.org
+            if (contact.organizations != null && contact.organizations.Count() > 0)
+            {
+                contactTask.Company = contact.organizations[0].name;
+                contactTask.JobTitle = contact.organizations[0].title;
+            }
+            #endregion
+
+            #region contact.phoneNumbers
+            if (contact.phoneNumbers != null && contact.phoneNumbers.Length > 0)
+            {
+                foreach (JSONContactField field in contact.phoneNumbers)
+                {
+                    string fieldType = field.type.ToLower();
+                    if (fieldType == "work")
+                    {
+                        contactTask.WorkPhone = field.value;
+                    }
+                    else if (fieldType == "home")
+                    {
+                        contactTask.HomePhone = field.value;
+                    }
+                    else if (fieldType == "mobile")
+                    {
+                        contactTask.MobilePhone = field.value;
+                    }
+                }
+            }
+            #endregion
+
+            #region contact.emails
+            if (contact.emails != null && contact.emails.Length > 0)
+            {
+                foreach (JSONContactField field in contact.emails)
+                {
+                    string fieldType = field.type.ToLower();
+                    if (fieldType == "work")
+                    {
+                        contactTask.WorkEmail = field.value;
+                    }
+                    else if (fieldType == "home" || fieldType == "personal")
+                    {
+                        contactTask.PersonalEmail = field.value;
+                    }
+                    else
+                    {
+                        contactTask.OtherEmail = field.value;
+                    }
+                }
+            }
+            #endregion
+
+            #region contact.addresses
+            if (contact.addresses != null && contact.addresses.Length > 0)
+            {
+                foreach (JSONContactAddress address in contact.addresses)
+                {
+                    string fieldType = address.type.ToLower();
+                    if (fieldType == "work")
+                    {
+                        contactTask.WorkAddressCity = address.locality;
+                        contactTask.WorkAddressCountry = address.country;
+                        contactTask.WorkAddressState = address.region;
+                        contactTask.WorkAddressStreet = address.streetAddress;
+                        contactTask.WorkAddressZipCode = address.postalCode;
+                    }
+                    else if (fieldType == "home" || fieldType == "personal")
+                    {
+                        contactTask.HomeAddressCity = address.locality;
+                        contactTask.HomeAddressCountry = address.country;
+                        contactTask.HomeAddressState = address.region;
+                        contactTask.HomeAddressStreet = address.streetAddress;
+                        contactTask.HomeAddressZipCode = address.postalCode;
+                    }
+                    else
+                    {
+                        // no other address fields available ...
+                        Debug.WriteLine("Creating contact with unsupported address type :: " + address.type);
+                    }
+                }
+            }
+            #endregion
+
+
+            contactTask.Completed += new EventHandler<SaveContactResult>(contactTask_Completed);
+            contactTask.Show();
+
+            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, new string[]{}));
+        }
+
+        void contactTask_Completed(object sender, SaveContactResult e)
+        {
+            SaveContactTask task = sender as SaveContactTask;
+
+            if (e.TaskResult == TaskResult.OK)
+            {
+                DeviceContacts deviceContacts = new DeviceContacts();
+                deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(postAdd_SearchCompleted);
+                deviceContacts.SearchAsync(task.FirstName + " " + task.LastName, FilterKind.DisplayName, task);
+            }
+            else if (e.TaskResult == TaskResult.Cancel)
+            {
+
+            }
+        }
+
+        void postAdd_SearchCompleted(object sender, ContactsSearchEventArgs e)
+        {
+            if (e.Results.Count() > 0)
+            {
+                List<Contact> foundContacts = new List<Contact>();
+
+                int n = (from Contact contact in e.Results select contact.GetHashCode()).Max();
+                Contact newContact = (from Contact contact in e.Results
+                                      where contact.GetHashCode() == n
+                                      select contact).First();
+
+                DispatchCommandResult(new PluginResult(PluginResult.Status.OK, FormatJSONContact(newContact,null)));
+            }
+            else
+            {
+                DispatchCommandResult(new PluginResult(PluginResult.Status.NO_RESULT));
+            }
+        }
+
+
+        // TODO: we need to be able to pass a search param in.
+        public void search(string searchCriteria)
+        {
+            ContactSearchParams searchParams = JSON.JsonHelper.Deserialize<ContactSearchParams>(searchCriteria);
+
+            if(searchParams.options == null)
+            {
+                searchParams.options = new SearchOptions();
+                searchParams.options.filter = "";
+                searchParams.options.multiple = true;
+            }
+
+            DeviceContacts deviceContacts = new DeviceContacts();
+            deviceContacts.SearchCompleted += new EventHandler<ContactsSearchEventArgs>(contacts_SearchCompleted);
+
+            // default is to search all fields
+            FilterKind filterKind = FilterKind.None;
+            // if only one field is specified, we will try the 3 available DeviceContact search filters
+            if (searchParams.fields.Count() == 1)
+            {
+                if (searchParams.fields.Contains("name"))
+                {
+                    filterKind = FilterKind.DisplayName;
+                }
+                else if (searchParams.fields.Contains("emails"))
+                {
+                    filterKind = FilterKind.EmailAddress;
+                }
+                else if (searchParams.fields.Contains("phoneNumbers"))
+                {
+                    filterKind = FilterKind.PhoneNumber;
+                }
+            }
+
+            try
+            {
+  
+                deviceContacts.SearchAsync(searchParams.options.filter, filterKind, searchParams);
+            }
+            catch (Exception ex)
+            {
+                Debug.WriteLine("search contacts exception :: " + ex.Message);
+            }
+        }
+
+        private void contacts_SearchCompleted(object sender, ContactsSearchEventArgs e)
+        {
+            ContactSearchParams searchParams = (ContactSearchParams)e.State;
+
+            List<Contact> foundContacts = null;
+
+            // if we have multiple search fields
+            if (searchParams.options.filter.Length > 0 && searchParams.fields.Count() > 1)
+            {
+                foundContacts = new List<Contact>();
+                if(searchParams.fields.Contains("emails"))
+                {
+                    foundContacts.AddRange(from Contact con in e.Results
+                                       from ContactEmailAddress a in con.EmailAddresses
+                                       where a.EmailAddress.Contains(searchParams.options.filter)
+                                       select con);
+                }
+                if (searchParams.fields.Contains("displayName"))
+                {
+                    foundContacts.AddRange(from Contact con in e.Results
+                                           where con.DisplayName.Contains(searchParams.options.filter)
+                                            select con);
+                }
+                if (searchParams.fields.Contains("name"))
+                {
+                    foundContacts.AddRange(from Contact con in e.Results
+                                           where con.CompleteName != null && con.CompleteName.ToString().Contains(searchParams.options.filter)
+                                           select con);
+                }
+                if (searchParams.fields.Contains("phoneNumbers"))
+                {
+                    foundContacts.AddRange(from Contact con in e.Results
+                                           from ContactPhoneNumber a in con.PhoneNumbers
+                                           where a.PhoneNumber.Contains(searchParams.options.filter)
+                                           select con);
+                }
+                if (searchParams.fields.Contains("urls"))
+                {
+                    foundContacts.AddRange(from Contact con in e.Results
+                                           from string a in con.Websites
+                                           where a.Contains(searchParams.options.filter)
+                                           select con);
+                }
+            }
+            else
+            {
+                foundContacts = new List<Contact>(e.Results);
+            }
+
+            //List<string> contactList = new List<string>();
+
+            string strResult = "";
+
+            IEnumerable<Contact> distinctContacts = foundContacts.Distinct();
+            
+            foreach (Contact contact in distinctContacts)
+            {
+                strResult += FormatJSONContact(contact, null) + ",";
+
+                //contactList.Add(FormatJSONContact(contact, null));
+                if (!searchParams.options.multiple)
+                {
+                    break; // just return the first item
+                }
+            }
+            PluginResult result = new PluginResult(PluginResult.Status.OK);
+            result.Message = "[" + strResult.TrimEnd(',') + "]";
+            DispatchCommandResult(result);
+
+        }
+
+        private string FormatJSONPhoneNumbers(Contact con)
+        {
+            string retVal = "";
+            foreach (ContactPhoneNumber number in con.PhoneNumbers)
+            {
+                retVal += "\"" +  number.PhoneNumber + "\",";
+            }
+            return retVal.TrimEnd(',');
+        }
+
+        private string FormatJSONEmails(Contact con)
+        {
+            string retVal = "";
+            foreach (ContactEmailAddress address in con.EmailAddresses)
+            {
+                retVal += "\"" + address.EmailAddress + "\",";
+            }
+            return retVal.TrimEnd(',');
+        }
+
+        private string FormatJSONAddresses(Contact con)
+        {
+            string retVal = "";
+            foreach (ContactAddress address in con.Addresses)
+            {
+                retVal += "\"" + address.ToString() + "\",";
+            }
+            return retVal.TrimEnd(',');
+        }
+
+        private string FormatJSONWebsites(Contact con)
+        {
+            string retVal = "";
+            foreach (string website in con.Websites)
+            {
+                retVal += "\"" + website + "\",";
+            }
+            return retVal.TrimEnd(',');
+        }
+
+        private string FormatJSONContact(Contact con, string[] fields)
+        {
+            string contactFormatStr = "\"id\":\"{0}\"," +
+                                      "\"displayName\":\"{1}\"," +
+                                      "\"nickname\":\"{2}\"," +
+                                      "\"phoneNumbers\":[{3}]," +
+                                      "\"emails\":[{4}]," +
+                                      "\"addresses\":[{5}]," +
+                                      "\"urls\":[{6}]";
+
+            string jsonContact = String.Format(contactFormatStr, 
+                                               con.GetHashCode(), 
+                                               con.DisplayName, 
+                                               con.DisplayName, 
+                                               FormatJSONPhoneNumbers(con), 
+                                               FormatJSONEmails(con),
+                                               FormatJSONAddresses(con),
+                                               FormatJSONWebsites(con));
+
+            return "{" + jsonContact + "}";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/4789ce6d/framework/Cordova/Commands/DebugConsole.cs
----------------------------------------------------------------------
diff --git a/framework/Cordova/Commands/DebugConsole.cs b/framework/Cordova/Commands/DebugConsole.cs
new file mode 100644
index 0000000..9478a8d
--- /dev/null
+++ b/framework/Cordova/Commands/DebugConsole.cs
@@ -0,0 +1,49 @@
+/*  
+	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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using System.Diagnostics;
+
+namespace WP7GapClassLib.Cordova.Commands
+{
+
+    public class DebugConsole : BaseCommand
+    {
+        // warn, error
+        public void log(string msg)
+        {
+            Debug.WriteLine("Log:" + msg);
+        }
+
+        public void error(string msg)
+        {
+            Debug.WriteLine("Error:" + msg);
+        }
+
+        public void warn(string msg)
+        {
+            Debug.WriteLine("Warn:" + msg);
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cordova-wp7/blob/4789ce6d/framework/Cordova/Commands/Device.cs
----------------------------------------------------------------------
diff --git a/framework/Cordova/Commands/Device.cs b/framework/Cordova/Commands/Device.cs
new file mode 100644
index 0000000..a5b2bd5
--- /dev/null
+++ b/framework/Cordova/Commands/Device.cs
@@ -0,0 +1,123 @@
+/*  
+	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.
+*/
+
+using System;
+using System.Net;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Shapes;
+using Microsoft.Phone.Info;
+using System.IO.IsolatedStorage;
+using System.Windows.Resources;
+using System.IO;
+using System.Diagnostics;
+
+namespace WP7GapClassLib.Cordova.Commands
+{
+    public class Device : BaseCommand
+    {
+        public void Get(string notused)
+        {
+
+            string res = String.Format("\"name\":\"{0}\",\"phonegap\":\"{1}\",\"platform\":\"{2}\",\"uuid\":\"{3}\",\"version\":\"{4}\"",
+                                        this.name,
+                                        this.phonegap,
+                                        this.platform,
+                                        this.uuid,
+                                        this.version);
+
+
+            res = "{" + res + "}";
+
+            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, res));
+        }
+
+        public string name
+        {
+            get
+            {
+                return DeviceStatus.DeviceName;
+            }
+        }
+
+        public string phonegap
+        {
+            get
+            {
+                // TODO: should be able to dynamically read the Cordova version from somewhere...
+                return "1.4.1";
+            }
+        }
+
+        public string platform
+        {
+            get
+            {
+                return Environment.OSVersion.Platform.ToString();
+            }
+        }
+
+        public string uuid
+        {
+            get
+            {
+                string returnVal = "";
+                object id;
+                UserExtendedProperties.TryGetValue("ANID", out id);
+
+                if (id != null)
+                {
+                    returnVal = id.ToString().Substring(2, 32);
+                }
+                else
+                {
+                    returnVal = "???unknown???";
+
+                    using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
+                    {
+                        try
+                        {
+                            IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
+
+                            using (StreamReader reader = new StreamReader(fileStream))
+                            {
+                                returnVal = reader.ReadLine();
+                            }
+                        }
+                        catch (Exception /*ex*/)
+                        {
+
+                        }
+                    }
+                }
+
+                return returnVal;
+            }
+        }
+
+        public string version
+        {
+            get
+            {
+                return Environment.OSVersion.Version.ToString();
+            }
+        }
+
+    }
+}