using System;
using System.Collections.Generic;
using System.Linq;
using Crestron.SimplSharpPro.DeviceSupport;
using Newtonsoft.Json;
using PepperDash.Core;
using PepperDash.Essentials.Core;
using PepperDash.Essentials.Core.Bridges;
using PepperDash.Essentials.Core.Lighting;
using Serilog.Events;
namespace PepperDash.Essentials.Devices.Common.Lighting
{
///
/// Base class for lighting devices that support scenes
///
public abstract class LightingBase : EssentialsBridgeableDevice, ILightingScenes
{
#region ILightingScenes Members
///
/// Event fired when lighting scene changes
///
public event EventHandler LightingSceneChange;
///
/// Gets or sets the LightingScenes
///
public List LightingScenes { get; protected set; }
///
/// Gets or sets the CurrentLightingScene
///
public LightingScene CurrentLightingScene { get; protected set; }
///
/// Gets or sets the CurrentLightingSceneFeedback
///
public IntFeedback CurrentLightingSceneFeedback { get; protected set; }
#endregion
///
/// Initializes a new instance of the LightingBase class
///
/// The device key
/// The device name
protected LightingBase(string key, string name)
: base(key, name)
{
LightingScenes = new List();
CurrentLightingScene = new LightingScene();
//CurrentLightingSceneFeedback = new IntFeedback(() => { return int.Parse(this.CurrentLightingScene.ID); });
}
///
/// Selects the specified lighting scene
///
/// The lighting scene to select
public abstract void SelectScene(LightingScene scene);
///
/// SimulateSceneSelect method
///
public void SimulateSceneSelect(string sceneName)
{
Debug.LogMessage(LogEventLevel.Debug, this, "Simulating selection of scene '{0}'", sceneName);
var scene = LightingScenes.FirstOrDefault(s => s.Name.Equals(sceneName));
if (scene != null)
{
CurrentLightingScene = scene;
OnLightingSceneChange();
}
}
///
/// Sets the IsActive property on each scene and fires the LightingSceneChange event
///
protected void OnLightingSceneChange()
{
foreach (var scene in LightingScenes)
{
if (scene == CurrentLightingScene)
scene.IsActive = true;
else
scene.IsActive = false;
}
LightingSceneChange?.Invoke(this, new LightingSceneChangeEventArgs(CurrentLightingScene));
}
///
/// Links the lighting device to API with join map configuration
///
/// The lighting device to link
/// The trilist to link to
/// The starting join number
/// The join map key
/// The EISC API bridge
/// The configured join map
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, uint joinStart,
string joinMapKey, EiscApiAdvanced bridge)
{
var joinMap = new GenericLightingJoinMap(joinStart);
var joinMapSerialized = JoinMapHelper.GetSerializedJoinMapForDevice(joinMapKey);
if (!string.IsNullOrEmpty(joinMapSerialized))
joinMap = JsonConvert.DeserializeObject(joinMapSerialized);
if (bridge != null)
{
bridge.AddJoinMap(Key, joinMap);
}
else
{
Debug.LogMessage(LogEventLevel.Information, this, "Please update config to use 'eiscapiadvanced' to get all join map features for this device.");
}
return LinkLightingToApi(lightingDevice, trilist, joinMap);
}
///
/// Links the lighting device to API using an existing join map
///
/// The lighting device to link
/// The trilist to link to
/// The join map to use
/// The join map used for linking
protected GenericLightingJoinMap LinkLightingToApi(LightingBase lightingDevice, BasicTriList trilist, GenericLightingJoinMap joinMap)
{
Debug.LogMessage(LogEventLevel.Debug, "Linking to Trilist '{0}'", trilist.ID.ToString("X"));
Debug.LogMessage(LogEventLevel.Information, "Linking to Lighting Type {0}", lightingDevice.GetType().Name.ToString());
// GenericLighitng Actions & FeedBack
trilist.SetUShortSigAction(joinMap.SelectScene.JoinNumber, u => lightingDevice.SelectScene(lightingDevice.LightingScenes[u]));
var sceneIndex = 0;
foreach (var scene in lightingDevice.LightingScenes)
{
var index = sceneIndex;
trilist.SetSigTrueAction((uint)(joinMap.SelectSceneDirect.JoinNumber + index), () => lightingDevice.SelectScene(lightingDevice.LightingScenes[index]));
scene.IsActiveFeedback.LinkInputSig(trilist.BooleanInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)]);
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
sceneIndex++;
}
trilist.OnlineStatusChange += (sender, args) =>
{
if (!args.DeviceOnLine) return;
sceneIndex = 0;
foreach (var scene in lightingDevice.LightingScenes)
{
var index = sceneIndex;
trilist.StringInput[(uint)(joinMap.SelectSceneDirect.JoinNumber + index)].StringValue = scene.Name;
trilist.BooleanInput[(uint)(joinMap.ButtonVisibility.JoinNumber + index)].BoolValue = true;
scene.IsActiveFeedback.FireUpdate();
sceneIndex++;
}
};
return joinMap;
}
}
}