namespace Gma.QrCodeNet.Encoding.Masking.Scoring
{
	/// <summary>
	/// ISO/IEC 18004:2000 Chapter 8.8.2 Page 52
	/// </summary>
	internal class Penalty1 : Penalty
	{
		/// <summary>
		/// Calculate penalty value for first rule.
		/// </summary>
		internal override int PenaltyCalculate(BitMatrix matrix)
		{
			int penaltyValue = PenaltyCalculation(matrix, true) + PenaltyCalculation(matrix, false);
			return penaltyValue;
		}

		private int PenaltyCalculation(BitMatrix matrix, bool isHorizontal)
		{
			int penalty = 0;
			int width = matrix.Width;

			int i = 0;
			int j = 0;

			while (i < width)
			{
				while (j < width - 4)
				{
					bool preBit = isHorizontal
						? matrix[j + 4, i]
						: matrix[i, j + 4];
					int numSameBitCell = 1;

					for (int x = 1; x <= 4; x++)
					{
						bool bit = isHorizontal
							? matrix[j + 4 - x, i]
							: matrix[i, j + 4 - x];
						if (bit == preBit)
						{
							numSameBitCell++;
						}
						else
						{
							break;
						}
					}

					if (numSameBitCell == 1)
					{
						j += 4;
					}
					else
					{
						int x = 5;
						while ((j + x) < width)
						{
							bool bit = isHorizontal
								? matrix[j + x, i]
								: matrix[i, j + x];
							if (bit == preBit)
							{
								numSameBitCell++;
							}
							else
							{
								break;
							}
							x++;
						}
						if (numSameBitCell >= 5)
						{
							penalty += (3 + (numSameBitCell - 5));
						}

						j += x;
					}
				}
				j = 0;
				i++;
			}

			return penalty;
		}
	}
}
