/*
 * Copyright 2012 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#import "ZXQRCodeWriterTestCase.h"

static NSString *BASE_IMAGE_PATH = @"Resources/golden/qrcode/";

@implementation ZXQRCodeWriterTestCase

- (ZXImage *)loadImage:(NSString *)fileName {
  return [[ZXImage alloc] initWithURL:
           [[NSBundle bundleForClass:[self class]] URLForResource:
            [BASE_IMAGE_PATH stringByAppendingString:fileName] withExtension:nil]];
}

// In case the golden images are not monochromatic, convert the RGB values to greyscale.
- (ZXBitMatrix *)createMatrixFromImage:(ZXImage *)image {
  size_t width = image.width;
  size_t height = image.height;
  uint32_t *data;

  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(0, width, height, 8, width * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
  CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
  CGContextSetShouldAntialias(context, NO);

  CGContextDrawImage(context, CGRectMake(0, 0, width, height), image.cgimage);

  data = (uint32_t *) malloc(width * height * sizeof(uint32_t));
  memcpy(data, CGBitmapContextGetData(context), width * height * sizeof(uint32_t));

  ZXBitMatrix *matrix = [[ZXBitMatrix alloc] initWithWidth:(int)width height:(int)height];
  for (int y = 0; y < height; y++) {
    for (int x = 0; x < width; x++) {
      int pixel = data[y * width + x];
      int luminance = (306 * ((pixel >> 16) & 0xFF) +
                       601 * ((pixel >> 8) & 0xFF) +
                       117 * (pixel & 0xFF)) >> 10;
      if (luminance <= 0x7F) {
        [matrix setX:x y:y];
      }
    }
  }
  return matrix;
}

- (void)testQRCodeWriter {
  // The QR should be multiplied up to fit, with extra padding if necessary
  int bigEnough = 256;
  ZXQRCodeWriter *writer = [[ZXQRCodeWriter alloc] init];
  ZXBitMatrix *matrix = [writer encode:@"http://www.google.com/" format:kBarcodeFormatQRCode width:bigEnough
                                height:bigEnough hints:nil error:nil];
  STAssertNotNil(matrix, @"Matrix should not be nil");
  STAssertEquals(matrix.width, bigEnough, @"Width should be %d", bigEnough);
  STAssertEquals(matrix.height, bigEnough, @"Height should be %d", bigEnough);

  // The QR will not fit in this size, so the matrix should come back bigger
  int tooSmall = 20;
  matrix = [writer encode:@"http://www.google.com/" format:kBarcodeFormatQRCode width:tooSmall
                   height:tooSmall hints:nil error:nil];
  STAssertNotNil(matrix, @"Matrix should not be nil");
  STAssertTrue(tooSmall < matrix.width, @"Matrix width should be greater than %d", tooSmall);
  STAssertTrue(tooSmall < matrix.height, @"Matrix height should be greater than %d", tooSmall);

  // We should also be able to handle non-square requests by padding them
  int strangeWidth = 500;
  int strangeHeight = 100;
  matrix = [writer encode:@"http://www.google.com/" format:kBarcodeFormatQRCode width:strangeWidth
                   height:strangeHeight hints:nil error:nil];
  STAssertNotNil(matrix, @"Matrix should not be nil");
  STAssertEquals(matrix.width, strangeWidth, @"Width should be %d", strangeWidth);
  STAssertEquals(matrix.height, strangeHeight, @"Height should be %d", strangeHeight);
}

- (void)compareToGoldenFile:(NSString *)contents ecLevel:(ZXErrorCorrectionLevel *)ecLevel
                 resolution:(int)resolution fileName:(NSString *)fileName {
  ZXImage *image = [self loadImage:fileName];
  STAssertNotNil(image, @"Image should not be nil");
  ZXBitMatrix *goldenResult = [self createMatrixFromImage:image];
  STAssertNotNil(goldenResult, @"Golden result should not be nil");

  ZXEncodeHints *hints = [[ZXEncodeHints alloc] init];
  hints.errorCorrectionLevel = ecLevel;
  ZXQRCodeWriter *writer = [[ZXQRCodeWriter alloc] init];
  ZXBitMatrix *generatedResult = [writer encode:contents format:kBarcodeFormatQRCode width:resolution
                                         height:resolution hints:hints error:nil];

  STAssertEquals(generatedResult.width, resolution, @"Expected generatedResult width to be %d", resolution);
  STAssertEquals(generatedResult.height, resolution, @"Expected generatedResult height to be %d", resolution);
  STAssertEqualObjects(generatedResult, goldenResult, @"Expected generatedResult to equal goldenResult");
}

// Golden images are generated with "qrcode_sample.cc". The images are checked with both eye balls
// and cell phones. We expect pixel-perfect results, because the error correction level is known,
// and the pixel dimensions matches exactly.
- (void)testRegressionTest {
  [self compareToGoldenFile:@"http://www.google.com/" ecLevel:[ZXErrorCorrectionLevel errorCorrectionLevelM]
                 resolution:99 fileName:@"renderer-test-01.png"];

  [self compareToGoldenFile:@"12345" ecLevel:[ZXErrorCorrectionLevel errorCorrectionLevelL]
                 resolution:58 fileName:@"renderer-test-02.png"];

  // Test in Katakana in Shift_JIS.
  // TODO: this test is bogus now that byte mode has been basically fixed to assuming ISO-8859-1 encoding
  //  The real solution is to implement Kanji mode, in which case the golden file will be wrong again
  /*
   compareToGoldenFile(
   new String(new byte[] {(byte)0x83, 0x65, (byte)0x83, 0x58, (byte)0x83, 0x67}, "Shift_JIS"),
   ErrorCorrectionLevel.H, 145,
   "renderer-test-03.png");
   */
}

@end
