using System;
using System.Runtime.InteropServices.ComTypes;

namespace skyscraper5.Teletext.Wss
{
    public class WssDataBlock
    {
        public WssDataBlock(int i)
        {
            bool b0 = (i & 0x8000) != 0;
            bool b1 = (i & 0x4000) != 0;
            bool b2 = (i & 0x2000) != 0;
            bool b3 = (i & 0x2000) != 0;

            if (!b0 && !b1 && !b2 && b3)
            {
                AspectRatioLabel = AspectRatio._4_3;
                FullFormat = true;
                Position = Positioning.NotApplicable;
                Lines = 576;
            }
            else if (b0 && !b1 && !b2 && !b3)
            {
                AspectRatioLabel = AspectRatio._14_9;
                FullFormat = false;
                Position = Positioning.Centre;
                Lines = 504;
            }
            else if (!b0 && b1 && !b2 && !b3)
            {
                AspectRatioLabel = AspectRatio._14_9;
                FullFormat = false;
                Position = Positioning.Top;
                Lines = 504;
            }
            else if (b0 && b1 && !b2 && b3)
            {
                AspectRatioLabel = AspectRatio._16_9;
                FullFormat = false;
                Position = Positioning.Centre;
                Lines = 430;
            }
            else if (!b0 && !b1 && b2 && !b3)
            {
                AspectRatioLabel = AspectRatio._16_9;
                FullFormat = false;
                Position = Positioning.Top;
                Lines = 430;
            }
            else if (b0 && !b1 && b2 && b3)
            {
                AspectRatioLabel = AspectRatio.UltraWidescreen;
                FullFormat = false;
                Position = Positioning.Centre;
                Lines = null;
            }
            else if (!b0 && b1 && b2 && b3)
            {
                AspectRatioLabel = AspectRatio._14_9;
                FullFormat = true;
                Position = Positioning.Centre;
                Lines = 576;
            }
            else if (b0 && b1 && b2 && !b3)
            {
                AspectRatioLabel = AspectRatio._16_9;
                FullFormat = true;
                Position = Positioning.NotApplicable;
                Lines = 576;
            }

            FilmMode = (i & 0x1000) != 0;
            MotionAdaptiveColorPlus = (i & 0x0800) != 0;
            ModulatedHelper = (i & 0x0400) != 0;
            //(i & 0x0200) != 0;    //reserved
            SubtitlesWithinTeletext = (i & 0x0100) != 0;

            bool b9 = (i & 0x0080) != 0;
            bool b10 = (i & 0x0040) != 0;

            if (!b9 && !b10)
                SubtitlingMode = SubtitlingModeEnum.NoOpenSubtitles;
            else if (b9 && !b10)
                SubtitlingMode = SubtitlingModeEnum.InActiveImage;
            else if (!b9 && b10)
                SubtitlingMode = SubtitlingModeEnum.OutOfActiveImage;

            SurroundSound = (i & 0x0020) != 0;
            CopyrightAsserted = (i & 0x0010) != 0;
            CopyingRestricted = (i & 0x0008) != 0;
        }

        public bool CopyingRestricted { get; private set; }

        public bool CopyrightAsserted { get; private set; }

        public bool SurroundSound { get; private set; }

        public SubtitlingModeEnum SubtitlingMode { get; private set; }

        public bool SubtitlesWithinTeletext { get; private set; }

        public bool ModulatedHelper { get; private set; }

        public bool MotionAdaptiveColorPlus { get; private set; }

        public bool FilmMode { get; private set; }

        public int? Lines { get; private set; }

        public Positioning Position { get; private set; }

        public bool FullFormat { get; private set; }

        public AspectRatio AspectRatioLabel { get; private set; }

        public string AspectRatioToString()
        {
            string s = AspectRatioLabel.ToString();
            if (s[0] == '_')
                return s.Substring(1).Replace('_', ':');
            else
                return s;
        }

        public enum AspectRatio
        {
            _4_3,
            _14_9,
            _16_9,
            UltraWidescreen
        }

        public enum Positioning
        {
            NotApplicable,
            Centre,
            Top
        }

        public enum SubtitlingModeEnum
        {
            NoOpenSubtitles,
            InActiveImage,
            OutOfActiveImage
        }

        protected bool Equals(WssDataBlock other)
        {
            return CopyingRestricted == other.CopyingRestricted && CopyrightAsserted == other.CopyrightAsserted && SurroundSound == other.SurroundSound && SubtitlingMode == other.SubtitlingMode && SubtitlesWithinTeletext == other.SubtitlesWithinTeletext && ModulatedHelper == other.ModulatedHelper && MotionAdaptiveColorPlus == other.MotionAdaptiveColorPlus && FilmMode == other.FilmMode && Lines == other.Lines && Position == other.Position && FullFormat == other.FullFormat && AspectRatioLabel == other.AspectRatioLabel;
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != this.GetType()) return false;
            return Equals((WssDataBlock)obj);
        }

        public override int GetHashCode()
        {
            var hashCode = new HashCode();
            hashCode.Add(CopyingRestricted);
            hashCode.Add(CopyrightAsserted);
            hashCode.Add(SurroundSound);
            hashCode.Add((int)SubtitlingMode);
            hashCode.Add(SubtitlesWithinTeletext);
            hashCode.Add(ModulatedHelper);
            hashCode.Add(MotionAdaptiveColorPlus);
            hashCode.Add(FilmMode);
            hashCode.Add(Lines);
            hashCode.Add((int)Position);
            hashCode.Add(FullFormat);
            hashCode.Add((int)AspectRatioLabel);
            return hashCode.ToHashCode();
        }
    }
}