using System; //using System.IO; using System.Collections.Generic; using System.Linq; using System.Text; using Crestron.SimplSharp; using Crestron.SimplSharp.CrestronIO; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace PepperDash.Core.JsonToSimpl { public abstract class JsonToSimplMaster : IKeyed { /*****************************************************************************************/ /** Events **/ public event EventHandler BoolChange; public event EventHandler UshrtChange; public event EventHandler StringChange; protected List Children = new List(); /*****************************************************************************************/ /// /// Mirrors the Unique ID for now. /// public string Key { get { return UniqueID; } } public string UniqueID { get; protected set; } /// /// Merely for use in debug messages /// public string DebugName { get { return _DebugName; } set { if (DebugName == null) _DebugName = ""; else _DebugName = value; } } string _DebugName = ""; /// /// This will be prepended to all paths to allow path swapping or for more organized /// sub-paths /// public string PathPrefix { get; set; } /// /// This is added to the end of all paths /// public string PathSuffix { get; set; } /// /// Enables debugging output to the console. Certain error messages will be logged to the /// system's error log regardless of this setting /// public bool DebugOn { get; set; } /// /// Ushort helper for Debug property /// public ushort UDebug { get { return (ushort)(DebugOn ? 1 : 0); } set { DebugOn = (value == 1); CrestronConsole.PrintLine("JsonToSimpl debug={0}", DebugOn); } } public JObject JsonObject { get; protected set; } /*****************************************************************************************/ /** Privates **/ // The JSON file in JObject form // For gathering the incoming data protected Dictionary UnsavedValues = new Dictionary(); /*****************************************************************************************/ /// /// SIMPL+ default constructor. /// public JsonToSimplMaster() { } /// /// Sets up class - overriding methods should always call this. /// /// public virtual void Initialize(string uniqueId) { UniqueID = uniqueId; J2SGlobal.AddMaster(this); // Should not re-add } /// /// Adds a child "module" to this master /// /// public void AddChild(JsonToSimplChildObjectBase child) { if (Children.Contains(child)) return; Children.Add(child); } /// /// Called from the child to add changed or new values for saving /// public void AddUnsavedValue(string path, JValue value) { if (UnsavedValues.ContainsKey(path)) { Debug.Console(0, "Master[{0}] WARNING - Attempt to add duplicate value for path '{1}'.\r Ingoring. Please ensure that path does not exist on multiple modules.", UniqueID, path); } else UnsavedValues.Add(path, value); //Debug.Console(0, "Master[{0}] Unsaved size={1}", UniqueID, UnsavedValues.Count); } public abstract void Save(); //****************************************************************************************** public static class JsonFixes { public static JObject ParseObject(string json) { using (var reader = new JsonTextReader(new Crestron.SimplSharp.CrestronIO.StringReader(json))) { var startDepth = reader.Depth; var obj = JObject.Load(reader); if (startDepth != reader.Depth) throw new JsonSerializationException("Unenclosed json found"); return obj; } } public static JArray ParseArray(string json) { using (var reader = new JsonTextReader(new Crestron.SimplSharp.CrestronIO.StringReader(json))) { var startDepth = reader.Depth; var obj = JArray.Load(reader); if (startDepth != reader.Depth) throw new JsonSerializationException("Unenclosed json found"); return obj; } } } // Helpers for events //****************************************************************************************** protected void OnBoolChange(bool state, ushort index, ushort type) { if (BoolChange != null) { var args = new BoolChangeEventArgs(state, type); args.Index = index; BoolChange(this, args); } } //****************************************************************************************** protected void OnUshrtChange(ushort state, ushort index, ushort type) { if (UshrtChange != null) { var args = new UshrtChangeEventArgs(state, type); args.Index = index; UshrtChange(this, args); } } protected void OnStringChange(string value, ushort index, ushort type) { if (StringChange != null) { var args = new StringChangeEventArgs(value, type); args.Index = index; StringChange(this, args); } } } }