using Helper;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Model
{
    /// <summary>
    /// 歌词类
    /// </summary>
    [Serializable()]
    public class Lyric
    {
        public string Ti { get; set; }
        public string Ar { get; set; }
        public string Al { get; set; }
        public string By { get; set; }
        public int Offset { get; set; }
        public int Count { get { return Words.Count; } }
        /// <summary>
        /// 
        /// </summary>
        public List<LrcWord> Words { get; set; }
        /// <summary>
        /// 导出格式
        /// </summary>
        public string Export
        {
            get
            {
                StringBuilder str = new StringBuilder("");
                str.Append(string.Format("[ti:{0}]\n[ar:{1}]\n[al:{2}]\n[by:{3}]\n[offset:{4}]\r\n", Ti, Ar, Al, By, Offset));
                foreach (LrcWord i in Words)
                { str.Append(i.Export); }
                return str.ToString().Trim();
            }
        }
        public static Lyric Create(string[] text)
        {
            Lyric l = new Lyric();
            foreach (string i in text)
            {
                l.Words.Add(new LrcWord(i));
            }
            return l;
        }
        public string Text
        {
            get
            {
                StringBuilder str = new StringBuilder("");
                foreach (LrcWord i in Words)
                { str.Append(i.Word + "\n"); }
                return str.ToString().Trim();
            }
        }
        public Lyric Speed(double rate)
        {
            foreach (LrcWord item in Words)
            {
                item.Time /= rate;
            }
            return this;
        }
        /// <summary>
        /// 保存歌词
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="en">编码</param>
        public void Save(string path, Encoding en)
        {
            File.Delete(path);
            File.AppendAllText(path, Export, en);
        }
        public void SaveText(string path, Encoding en)
        {
            File.Delete(path);
            File.AppendAllText(path, Text, en);
        }
        /// <summary>
        /// Lyrec默认构造
        /// </summary>
        public Lyric()
        {
            Words = new List<LrcWord>();
        }
        /// <summary>
        /// 从文件加载
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="en">编码</param>
        public static Lyric FromFile(string path, Encoding en)
        {
            string str = File.ReadAllText(path, en);
            return Parse(str);
        }
        /// <summary>
        /// 从网络路径加载
        /// </summary>
        /// <param name="path">路径</param>
        /// <param name="en">编码</param>
        public static Lyric FromNet(string path, Encoding en)
        {
            string str = HttpHelper.Get(path, en);
            return Parse(str);
        }
        /// <summary>
        /// 从字符串加载
        /// </summary>
        public static Lyric Parse(string str)
        {
            str = ConvertEx.SignToEnglish(str).Replace(@"\n","\n");
            string[] words = str.Split('\n');
            Lyric l = new Lyric();
            l.Ti = CommonHelper.GetMiddleText(str, "[ti:", "]");
            l.Ar = CommonHelper.GetMiddleText(str, "[ar:", "]");
            l.Al = CommonHelper.GetMiddleText(str, "[al:", "]");
            l.By = CommonHelper.GetMiddleText(str, "[by:", "]");
            l.Offset = ConvertEx.ToInt32(CommonHelper.GetMiddleText(str, "[offset:", "]"), 0);
            l.Words = new List<LrcWord>();
            foreach (string i in words)
            {
                LrcWord lw = LrcWord.Parse(i);
                if (lw != null)
                { l.Words.Add(lw); }
            }
            if (l.Words.Count == 0)
            { return null; }
            return l;
        }
        /// <summary>
        /// 转换酷我歌曲
        /// </summary>
        /// <param name="id">音乐id</param>
        public static Lyric ParseKuwo(string id)
        {
            string src = ConvertEx.SignToEnglish(HttpHelper.Get("http://www.kuwo.cn/newh5/singles/songinfoandlrc?musicId=" + id));
            Lyric l = new Lyric();
            l.Words = new List<LrcWord>();
            string[] words = CommonHelper.GetMiddleTextMultiple(src, "{\"line", "\"}");
            foreach (string i in words)
            {
                LrcWord lw = LrcWord.ParseKuwo(i);
                if (lw != null)
                { l.Words.Add(lw); }
            }
            return l;
        }
    }
    /// <summary>
    /// 歌词文本类
    /// </summary>
    [Serializable()]
    public class LrcWord
    {
        public double Time { get; set; }
        public string Word { get; set; }
        /// <summary>
        /// 导出格式
        /// </summary>
        public string Export
        { get { return string.Format("[{0}:{1:f3}]{2}\n", Math.Floor(Time / 60), Time % 60, Word); } }
        /// <summary>
        /// LrcWord有参构造
        /// </summary>
        /// <param name="time">时间</param>
        /// <param name="word">文本</param>
        private LrcWord(double time, string word)
        {
            Time = time;
            Word = word;
        }
        public LrcWord(string text)
        { Word = text; }
        /// <summary>
        /// 将字符串转换为歌词文本对象
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static LrcWord Parse(string s)
        {
            try
            {
                Regex regex = new Regex(@"\[([0-9.:]*)\]+(.*)", RegexOptions.Compiled);
                MatchCollection mc = regex.Matches(s.Trim());
                double time = TimeSpan.Parse("00:" + mc[0].Groups[1].Value).TotalSeconds;
                string word = mc[0].Groups[2].Value;
                return new LrcWord(time, word);
            }
            catch (Exception)
            { return null; }
        }
        /// <summary>
        /// 解析酷我歌词(已失效)
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static LrcWord ParseKuwo(string s)
        {
            try
            {
                double time = double.Parse(CommonHelper.GetRightText(s, "ime\":\""));
                return new LrcWord(time, CommonHelper.GetMiddleText(s, "Lyric\":\"", "\",\"time"));
            }
            catch (Exception)
            { return null; }
        }
        public override string ToString()
        {
            return Word;
        }
    }
}
