inline Segmentation::XIndexes Segmentation::GetXIndexes(const ImageLib::ImageGray & Img) {
	Histogram VerticalHistogram(Img.width());
	VerticalHistogram.CreateVerticalHistogram(Img);
	//VerticalHistogram.Save("VerticalHistogram");
	 
	XIndexes Indexes;
	bool LookingForX1 = true;
	float MinValueX = VerticalHistogram.MinValue() + MARGE;

	for (int i = 0; i < VerticalHistogram.Length(); i++) {
		if (VerticalHistogram[i] > MinValueX && LookingForX1) {
			Indexes.X1.push_back(i);
			LookingForX1 = false;
		}
		else if (VerticalHistogram[i] < MinValueX && !LookingForX1) {
			Indexes.X2.push_back(i);
			LookingForX1 = true;
		}
	}

	if (Indexes.X2.size() < Indexes.X1.size())
		Indexes.X2.push_back(Img.width());

	return Indexes;
}
char StaticOCR::Apply(const ImageLib::ImageGray & Img) {
	ImageLib::ImageGray Image = ImageResizer::ScaleTo(Img, 60);
	//ImageLib::saveImg(Image, "Resized.bmp");

	int imageWidth = Image.width();
	int imageHeight = Image.height();
	int blockHeight = imageHeight / 3;
	int blockWidth = imageWidth / 3;
	float pixelCount = 0;
	//Loop through all the percentage blocks of the image.
	for (int blockY = 0; blockY < 3; blockY++) {
		for (int blockX = 0; blockX < 3; blockX++) {
			//Loop trough a single block
			for (int imageY = blockHeight * blockY; imageY < blockHeight * (blockY + 1); imageY++) {
				for (int imageX = blockWidth * blockX; imageX < blockWidth * (blockX + 1); imageX++) {
					//Check wether the pixelvalue is black.
					if (Image.at(imageX, imageY) < 80) {
						//If so increase the pixelcount
						pixelCount++;
					}
				}
			}
			//Calculate the percentage and store it in the blockpercentage array.
			percentages[blockX + (blockY * 3)] = (pixelCount / (blockHeight * blockWidth) * 100);
			pixelCount = 0;
		}
	}

	char c;
	for (int i = 0; i < MAX_ITERATIONS; i++) {
		c = compareAllBlocks(marge + (i * extra_marge));

		if (c != '#')
			break;
	}

	return c;

}
inline Segmentation::YIndexes Segmentation::GetYIndexes(const ImageLib::ImageGray & Img) {
	Histogram HorizontalHistogram(Img.height());
	HorizontalHistogram.CreateHorizontalHistogram(Img);
	//HorizontalHistogram.Save("HorizontalHistogram");

	YIndexes Indexes;
	Indexes.Y1 = 0;
	Indexes.Y2 = Img.height();
	bool LookingForY1 = true;
	float MinValueY = HorizontalHistogram.MinValue() + MARGE;

	for (int i = 0; i < HorizontalHistogram.Length(); i++) {
		if (HorizontalHistogram[i] > MinValueY && LookingForY1) {
			Indexes.Y1 = i;
			LookingForY1 = false;
		}
		else if (HorizontalHistogram[i] < MinValueY && !LookingForY1) {
			Indexes.Y2 = i;
			break;
		}
	}

	return Indexes;
}
inline SegmentedImages Segmentation::CreateImages(const ImageLib::ImageGray & Img, const Segmentation::XIndexes & IndexX, const Segmentation::YIndexes & IndexY) {
	int NewWidth;
	int NewHeight = IndexY.Y2 - IndexY.Y1;

	SegmentedImages Images;
	int CharacterCount = IndexX.X1.size();
	for (int i = 0; i < CharacterCount; i++) {
		NewWidth = IndexX.X2[i] - IndexX.X1[i];

		Images.push_back(ImageLib::ImageGray(NewWidth, NewHeight));

		for (int x = 0; x < NewWidth; x++)
		for (int y = 0; y < NewHeight; y++)
			Images[i].at(x, y) = Img.at(x + IndexX.X1[i], y + IndexY.Y1);
	}

	return Images;
}
ImageLib::ImageGray ImageResizer::ScaleTo(const ImageLib::ImageGray & Image, int Size) {
	ImageLib::ImageGray ReturnImage = ImageLib::ImageGray(Size, Size);
	ImageLib::ImageGray SourceImage = PutImageIn1x1Ratio(Image);

	float Scale = (float)SourceImage.width() / (float)Size;

	for (int y = 0; y < Size; y++)
	for (int x = 0; x < Size; x++) {

		int oldX = (int)(round(Scale * (float)x + 0.0f  * (float)y));
		int oldY = (int)(round(0.0f  * (float)x + Scale * (float)y));

		if (oldX >= 0 && oldX < SourceImage.width() && oldY >= 0 && oldY < SourceImage.height())
			ReturnImage.at(x, y) = SourceImage.at(oldX, oldY);
		else
			ReturnImage.at(x, y) = 150;
	}

	return ReturnImage;
}
void ImageResizer::HorizontalPadding(const ImageLib::ImageGray & Source, ImageLib::ImageGray & Destination) {
	int Size = Destination.height();
	int OldSize = Source.height();

	int Padding = (Size - OldSize) / 2;

	for (int y = 0; y < Padding; y++)
	for (int x = 0; x < Size; x++)
		Destination.at(x, y) = 255;

	for (int y = Padding; y < OldSize + Padding; y++)
	for (int x = 0; x < Size; x++)
		Destination.at(x, y) = Source.at(x,y - Padding);

	int adPadding = Padding * 2;
	if (((Size - OldSize) % 2) != 0) {
		adPadding += 1;
	}

	for (int y = OldSize + Padding; y < OldSize + adPadding; y++)
	for (int x = 0; x < OldSize; x++)
		Destination.at(x, y) = 255;
}
void ImageResizer::VerticalPadding(const ImageLib::ImageGray & Source, ImageLib::ImageGray & Destination) {
	int Size = Destination.width();
	int OldSize = Source.width();
	
	int Padding = (Size - OldSize) / 2;

	for (int y = 0; y < Size; y++)
	for (int x = 0; x < Padding; x++)
		Destination.at(x, y) = 255;

	for (int y = 0; y < Size; y++)
	for (int x = Padding; x < OldSize + Padding; x++)
		Destination.at(x, y) = Source.at(x - Padding, y);

	int adPadding = Padding * 2;
	if (((Size - OldSize) % 2) != 0) {
		adPadding += 1;
	}

	for (int y = 0; y < Size; y++)
	for (int x = OldSize + Padding; x < OldSize + adPadding; x++)
		Destination.at(x, y) = 255;
}
ImageLib::ImageGray ImageResizer::PutImageIn1x1Ratio(const ImageLib::ImageGray & Image) {
	int OldSize;
	int Size;

	if (Image.width() < Image.height()) {
		Size = Image.height();
		OldSize = Image.width();

		ImageLib::ImageGray ReturnImage = ImageLib::ImageGray(Size, Size);
		VerticalPadding(Image, ReturnImage);

		return ReturnImage;
	}
	else {
		Size = Image.width();
		OldSize = Image.height();

		ImageLib::ImageGray ReturnImage = ImageLib::ImageGray(Size, Size);
		HorizontalPadding(Image, ReturnImage);

		return ReturnImage;
	}
}