public void TestCurrentTimelineTime()
        {
            AtemMockServerWrapper.Each(_output, _pool, null, DeviceTestCases.HyperDecks, helper =>
            {
                ImmutableList <ICommand> allCommands = helper.Server.GetParsedDataDump();
                List <HyperDeckSettingsGetCommand> settingsCommands = allCommands.OfType <HyperDeckSettingsGetCommand>().ToList();
                List <HyperDeckPlayerGetCommand> playerCommands     = allCommands.OfType <HyperDeckPlayerGetCommand>().ToList();

                foreach (IBMDSwitcherHyperDeck deck in GetHyperDecks(helper))
                {
                    deck.GetId(out long id);

                    HyperDeckSettingsGetCommand cmd   = settingsCommands.Single(c => c.Id == id);
                    HyperDeckPlayerGetCommand playCmd = playerCommands.Single(c => c.Id == id);

                    // Force it to be connected
                    AtemState stateBefore = helper.Helper.BuildLibState();
                    cmd.Status            = HyperDeckConnectionStatus.Connected;
                    stateBefore.Hyperdecks[(int)id].Settings.Status = HyperDeckConnectionStatus.Connected;
                    stateBefore.Hyperdecks[(int)id].Player.State    = HyperDeckPlayerState.Idle;
                    helper.SendFromServerAndWaitForChange(stateBefore, cmd);

                    // Define a clip
                    stateBefore.Hyperdecks[(int)id].Clips =
                        UpdaterUtil.CreateList(1, i => new HyperdeckState.ClipState());
                    helper.SendFromServerAndWaitForChange(stateBefore, new HyperDeckClipCountCommand
                    {
                        Id        = (uint)id,
                        ClipCount = 1,
                    });
                    var clipCmd = new HyperDeckClipInfoCommand
                    {
                        HyperdeckId = (uint)id,
                        ClipId      = 0,
                        Name        = "something 123",
                        Duration    = new HyperDeckTime {
                            Hour = 24
                        },
                        TimelineStart = new HyperDeckTime(),
                        TimelineEnd   = new HyperDeckTime {
                            Hour = 24
                        },
                    };
                    AtemStateBuilder.Update(stateBefore, clipCmd);
                    helper.SendFromServerAndWaitForChange(stateBefore, clipCmd);
                    stateBefore = helper.Helper.BuildLibState();

                    // Set the clip to be playing
                    HyperDeckStorageGetCommand srcCmd = new HyperDeckStorageGetCommand
                    {
                        Id = (uint)id,
                        ActiveStorageMedia  = 0,
                        CurrentClipId       = 0,
                        FrameRate           = 50000,
                        TimeScale           = 1000,
                        RemainingRecordTime = new HyperDeckTime(),
                    };
                    AtemStateBuilder.Update(stateBefore, srcCmd);
                    helper.SendFromServerAndWaitForChange(stateBefore, srcCmd);
                    stateBefore = helper.Helper.BuildLibState();

                    HyperdeckState deckState = stateBefore.Hyperdecks[(int)id];

                    // Now try the stuff
                    for (int i = 0; i < 5; i++)
                    {
                        uint hours   = (uint)Randomiser.RangeInt(1, 20);
                        uint minutes = (uint)Randomiser.RangeInt(1, 59);
                        uint seconds = (uint)Randomiser.RangeInt(1, 59);
                        uint frames  = (uint)Randomiser.RangeInt(1, 20);
                        deckState.Player.ClipTime = new HyperDeckTime();
                        playCmd.TimelineTime      = deckState.Player.TimelineTime = new HyperDeckTime
                        {
                            Hour = hours, Minute = minutes, Second = seconds, Frame = frames
                        };

                        helper.SendFromServerAndWaitForChange(stateBefore, playCmd);
                    }
                }
            });
        }
        public void TestClipsInfo()
        {
            AtemMockServerWrapper.Each(_output, _pool, null, DeviceTestCases.HyperDecks, helper =>
            {
                ImmutableList <ICommand> allCommands = helper.Server.GetParsedDataDump();
                List <HyperDeckSettingsGetCommand> settingsCommands = allCommands.OfType <HyperDeckSettingsGetCommand>().ToList();

                foreach (IBMDSwitcherHyperDeck deck in GetHyperDecks(helper))
                {
                    deck.GetId(out long id);
                    HyperDeckSettingsGetCommand cmd = settingsCommands.Single(c => c.Id == id);

                    // Force it to be connected
                    AtemState stateBefore = helper.Helper.BuildLibState();
                    cmd.Status            = HyperDeckConnectionStatus.Connected;
                    stateBefore.Hyperdecks[(int)id].Settings.Status = HyperDeckConnectionStatus.Connected;
                    stateBefore.Hyperdecks[(int)id].Player.State    = HyperDeckPlayerState.Idle;
                    helper.SendFromServerAndWaitForChange(stateBefore, cmd);

                    stateBefore = helper.Helper.BuildLibState();
                    HyperdeckState hyperdeckState = stateBefore.Hyperdecks[(int)id];

                    for (int i = 0; i < 5; i++)
                    {
                        // Change the length
                        var newCmd = new HyperDeckClipCountCommand
                        {
                            Id        = (uint)id,
                            ClipCount = (uint)Randomiser.RangeInt(2, 5)
                        };
                        hyperdeckState.Clips = UpdaterUtil
                                               .CreateList(newCmd.ClipCount, o => new HyperdeckState.ClipState());

                        helper.SendFromServerAndWaitForChange(stateBefore, newCmd, -1, (sdkState, libState) =>
                        {
                            // Sdk likes to randomly give back some stale data, so lets focus on just the length
                            sdkState.Hyperdecks[(int)id].Clips = UpdaterUtil
                                                                 .CreateList((uint)sdkState.Hyperdecks[(int)id].Clips.Count,
                                                                             o => new HyperdeckState.ClipState());
                        });

                        // Now fill in some clip info
                        var infoCmd = new HyperDeckClipInfoCommand
                        {
                            HyperdeckId = (uint)id,
                            ClipId      = 1,
                            Name        = Randomiser.String(64),

                            TimelineStart = new HyperDeckTime
                            {
                                Hour   = (uint)Randomiser.RangeInt(2, 8),
                                Minute = (uint)Randomiser.RangeInt(2, 50),
                                Second = (uint)Randomiser.RangeInt(2, 50),
                                Frame  = (uint)Randomiser.RangeInt(2, 50),
                            },

                            TimelineEnd = new HyperDeckTime
                            {
                                Hour   = (uint)Randomiser.RangeInt(4, 18),
                                Minute = (uint)Randomiser.RangeInt(2, 50),
                                Second = (uint)Randomiser.RangeInt(2, 50),
                                Frame  = (uint)Randomiser.RangeInt(2, 50),
                            },

                            Duration = new HyperDeckTime
                            {
                                Hour   = (uint)Randomiser.RangeInt(10, 20),
                                Minute = (uint)Randomiser.RangeInt(2, 50),
                                Second = (uint)Randomiser.RangeInt(2, 50),
                                Frame  = (uint)Randomiser.RangeInt(2, 50),
                            },
                        };
                        hyperdeckState.Clips[(int)infoCmd.ClipId].Name          = infoCmd.Name;
                        hyperdeckState.Clips[(int)infoCmd.ClipId].Duration      = infoCmd.Duration;
                        hyperdeckState.Clips[(int)infoCmd.ClipId].TimelineStart = infoCmd.TimelineStart;
                        hyperdeckState.Clips[(int)infoCmd.ClipId].TimelineEnd   = infoCmd.TimelineEnd;

                        helper.SendFromServerAndWaitForChange(stateBefore, infoCmd);
                    }
                }
            });
        }