/*******************************************************
  *
  * 时间计算方式:
  *     - offset:        全局偏移量
  *     - subtitle:      字幕时间
  *     - currentTime:   计时器当前时间
  *
  *  offset + subtitle = currentTime
  ******************************************************/
 public SubtitleGroup(SubtitleManager manager, LyricFile file, int spaceTime = 300)
 {
     parentManager = manager;
     orgOffset = file.Offset;
     offset = orgOffset;
     currentTime = 0;
     lyrics = new LinkedList<SubtitleContent>();
     lyrics.AddLast(new SubtitleContent(String.Empty));
     foreach (Lyric lyric in file.Lyrics)
     {
         if (!String.IsNullOrWhiteSpace(lyrics.Last.Value.Content)
             && lyrics.Last.Value.StartTime + spaceTime * 2 < lyric.TimeTag)
         {
             lyrics.Last.Value.EndTime = lyric.TimeTag - spaceTime;
             lyrics.AddLast(new SubtitleContent(String.Empty, lyric.TimeTag - spaceTime, lyric.TimeTag));
         }
         else
             lyrics.Last.Value.EndTime = lyric.TimeTag;
         lyrics.AddLast(new SubtitleContent(lyric.Content, lyric.TimeTag, lyric.TimeTag));
     }
     currentSubtitle = lyrics.First;
     Title = file.FileName;
 }
        public void StartBarrager()
        {
            started = true;

            int exStyle = ApiHelper.GetWindowLong(Handle, ApiHelper.GWL_EXSTYLE);
            ApiHelper.SetWindowLong(Handle, ApiHelper.GWL_EXSTYLE, exStyle | ApiHelper.WS_EX_TRANSPARENT);

            // 隐藏弹幕快捷键。
            GlobalKeyHook.Instance.SetProcessor(hideKey, k =>
            {
                barrageManager.Visible = !barrageManager.Visible;
                ShowNotice(barrageManager.Visible ? "弹幕显示" : "弹幕隐藏");
                return true;
            });

            // 实例化弹幕源。

            inputs = new List<CommentInput>();
            foreach (KeyValuePair<string, string> keyValue in confs["Input"])
            {
                try
                {
                    Assembly assembly = Assembly.LoadFrom(keyValue.Value);
                    foreach (Type type in assembly.GetTypes())
                    {
                        if (type.Name.Equals(keyValue.Key))
                        {
                            CommentInput input = (CommentInput)Activator.CreateInstance(type);
                            input.Initialize(confs[keyValue.Key]);
                            input.Comment += (sender, ce) => barrageManager.AddBarrage(ce.Comment);
                            Debugger.Log("弹幕源: " + input.GetType().FullName);
                            inputs.Add(input);
                        }
                    }
                }
                catch (Exception exc)
                {
                    Debugger.Exception(exc);
                }
            }

            barrageManager = new BarrageManager(this, ClientSize, confs["Appearance"], confs["Action"]);
            subtitleManager = new SubtitleManager(this, ClientRectangle, confs["Subtitle"]);

            stopwatch = new System.Diagnostics.Stopwatch();
            stopwatch.Start();
            frameTimer = new Timer();
            frameTimer.Interval = 30;
            frameTimer.Tick += new EventHandler(frameTimer_Tick);
            frameTimer.Start();
        }