namespace Gma.QrCodeNet.Encoding.EncodingRegion;

/// <remarks>ISO/IEC 18004:2000 Chapter 8.7.3 Page 46</remarks>
internal static class Codeword
{
    internal static void TryEmbedCodewords(this TriStateMatrix tsMatrix, BitList codewords)
    {
        int sWidth = tsMatrix.Width;
        int codewordsSize = codewords.Count;

        int bitIndex = 0;
        int directionUp = -1;

        int x = sWidth - 1;
        int y = sWidth - 1;

        while (x > 0)
        {
            // Skip vertical timing pattern
            if (x == 6)
            {
                x -= 1;
            }

            while (y >= 0 && y < sWidth)
            {
                for (int xOffset = 0; xOffset < 2; xOffset++)
                {
                    int xPos = x - xOffset;
                    if (tsMatrix.MStatus(xPos, y) == MatrixStatus.None)
                    {
                        bool bit;
                        if (bitIndex < codewordsSize)
                        {
                            bit = codewords[bitIndex];
                            bitIndex++;
                        }
                        else
                        {
                            bit = false;
                        }

                        tsMatrix[xPos, y, MatrixStatus.Data] = bit;
                    }
                }

                y = NextY(y, directionUp);
            }

            directionUp = ChangeDirection(directionUp);
            y = NextY(y, directionUp);
            x -= 2;
        }

        if (bitIndex != codewordsSize)
        {
            throw new Exception($"Not all bits from {nameof(codewords)} consumed by matrix: {bitIndex} / {codewordsSize}.");
        }
    }

    internal static int NextY(int y, int directionUp)
    {
        return y + directionUp;
    }

    internal static int ChangeDirection(int directionUp)
    {
        return -directionUp;
    }
}