﻿using UnityEngine;

namespace JLGames.RocketDriver.Games.RpgMaterial.Common
{
    public struct GroupRandWeight : IDataRandomable
    {
        private readonly DataRandWeight[] m_Rands;

        public bool IsNone => null == m_Rands || m_Rands.Length == 0;

        public GroupRandWeight(DataRandWeight[] rands)
        {
            m_Rands = rands;
        }

        public DataNum RandToDataNum()
        {
            return m_Rands[RandIndex()].ToDataNum();
        }

        public DataOffset RandToDataOffset(bool negative)
        {
            return m_Rands[RandIndex()].ToDataOffset(negative);
        }

        public int RandIndex()
        {
            var all = 0;
            foreach (var ele in m_Rands)
            {
                all += ele.Weight;
            }

            var r = Random.Range(0, all);
            for (var index = m_Rands.Length - 1; index >= 0; index--)
            {
                r -= m_Rands[index].Weight;
                if (r < 0) return index;
            }

            return 0;
        }

        // static

        private const char SepField = ':';
        private const char SepEntity = '|';
        private const char SepGroup = '&';
        private static readonly GroupRandWeight m_None = new GroupRandWeight();

        public static GroupRandWeight FromString(string content, char sepEntity = SepEntity, char sepField = SepField)
        {
            if (string.IsNullOrEmpty(content)) return m_None;

            var rands = DataRandWeight.ArrayFromString(content, sepEntity, sepField);
            return new GroupRandWeight(rands);
        }

        public static GroupRandWeight[] ArrayFromString(string content, char sepGroup = SepGroup,
            char sepEntity = SepEntity, char sepField = SepField)
        {
            if (string.IsNullOrEmpty(content)) return null;
            var cs = content.Split(sepGroup);
            if (cs.Length == 0) return null;
            var rs = new GroupRandWeight[cs.Length];
            for (var index = 0; index < rs.Length; index++)
            {
                rs[index] = FromString(cs[index], sepEntity, sepField);
            }

            return rs;
        }
    }
}