import 'dart:typed_data';

import '../../image_exception.dart';
import '../../internal/internal.dart';
import '../../util/input_buffer.dart';
import '../../util/output_buffer.dart';
import 'exr_channel.dart';
import 'exr_compressor.dart';
import 'exr_huffman.dart';
import 'exr_part.dart';
import 'exr_wavelet.dart';

/**
 * Wavelet compression
 */
abstract class ExrPizCompressor extends ExrCompressor {
  factory ExrPizCompressor(ExrPart header, int maxScanLineSize,
                           int numScanLines) = InternalExrPizCompressor;
}

@internal
class InternalExrPizCompressor extends InternalExrCompressor implements ExrPizCompressor {
  InternalExrPizCompressor(ExrPart header, this._maxScanLineSize, this._numScanLines) :
    super(header) {
    _channelData = new List<_PizChannelData>(header.channels.length);
    for (int i = 0; i < _channelData.length; ++i) {
      _channelData[i] = new _PizChannelData();
    }

    int tmpBufferSize = (_maxScanLineSize * _numScanLines) ~/ 2;
    _tmpBuffer = new Uint16List(tmpBufferSize);
  }

  int numScanLines() => _numScanLines;

  Uint8List compress(InputBuffer inPtr, int x, int y,
                     [int width, int height]) {
    throw new ImageException('Piz compression not yet supported.');
  }

  Uint8List uncompress(InputBuffer inPtr, int x, int y,
                       [int width, int height]) {
    if (width == null) {
      width = header.width;
    }
    if (height == null) {
      height = header.linesInBuffer;
    }

    int minX = x;
    int maxX = x + width - 1;
    int minY = y;
    int maxY = y + height - 1;

    if (maxX > header.width) {
      maxX = header.width - 1;
    }
    if (maxY > header.height) {
      maxY = header.height - 1;
    }

    decodedWidth = (maxX - minX) + 1;
    decodedHeight = (maxY - minY) + 1;

    int tmpBufferEnd = 0;
    List<ExrChannel> channels = header.channels;
    final int numChannels = channels.length;

    for (int i = 0; i < numChannels; ++i) {
      ExrChannel ch = channels[i];
      _PizChannelData cd = _channelData[i];
      cd.start = tmpBufferEnd;
      cd.end = cd.start;

      cd.nx = numSamples(ch.xSampling, minX, maxX);
      cd.ny = numSamples(ch.ySampling, minY, maxY);
      cd.ys = ch.ySampling;

      cd.size = ch.size ~/ 2; //2=size(HALF)

      tmpBufferEnd += cd.nx * cd.ny * cd.size;
    }

    int minNonZero = inPtr.readUint16();
    int maxNonZero = inPtr.readUint16();

    if (maxNonZero >= BITMAP_SIZE) {
      throw new ImageException("Error in header for PIZ-compressed data "
                               "(invalid bitmap size).");
    }

    Uint8List bitmap = new Uint8List(BITMAP_SIZE);
    if (minNonZero <= maxNonZero) {
      InputBuffer b = inPtr.readBytes(maxNonZero - minNonZero + 1);
      for (int i = 0, j = minNonZero, len = b.length; i < len; ++i) {
        bitmap[j++] = b[i];
      }
    }

    Uint16List lut = new Uint16List(USHORT_RANGE);
    int maxValue = _reverseLutFromBitmap(bitmap, lut);

    // Huffman decoding
    int length = inPtr.readUint32();
    ExrHuffman.uncompress(inPtr, length, _tmpBuffer, tmpBufferEnd);

    // Wavelet decoding
    for (int i = 0; i < numChannels; ++i) {
      _PizChannelData cd = _channelData[i];
      for (int j = 0; j < cd.size; ++j) {
        ExrWavelet.decode(_tmpBuffer, cd.start + j, cd.nx, cd.size, cd.ny,
                          cd.nx * cd.size, maxValue);
      }
    }

    // Expand the pixel data to their original range
    _applyLut(lut, _tmpBuffer, tmpBufferEnd);

    if (_output == null) {
      _output = new OutputBuffer(size: (_maxScanLineSize * _numScanLines) +
                                       (65536 + 8192));
    }
    _output.rewind();

    //int count = 0;
    // Rearrange the pixel data into the format expected by the caller.
    for (int y = minY; y <= maxY; ++y) {
      for (int i = 0; i < numChannels; ++i) {
        _PizChannelData cd = _channelData[i];

        if ((y % cd.ys) != 0) {
          continue;
        }

        for (int x = cd.nx * cd.size; x > 0; --x) {
          _output.writeUint16(_tmpBuffer[cd.end++]);
        }
      }
    }

    return _output.getBytes();
  }

  void _applyLut(List<int> lut, List<int> data, int nData) {
    for (int i = 0; i < nData; ++i) {
      data[i] = lut[data[i]];
    }
  }

  int _reverseLutFromBitmap(Uint8List bitmap, Uint16List lut) {
    int k = 0;
    for (int i = 0; i < USHORT_RANGE; ++i) {
      if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))) != 0) {
        lut[k++] = i;
      }
    }

    int n = k - 1;

    while (k < USHORT_RANGE) {
      lut[k++] = 0;
    }

    return n;   // maximum k where lut[k] is non-zero,
  }

  static const int USHORT_RANGE = 1 << 16;
  static const int BITMAP_SIZE = 8192;

  OutputBuffer _output;
  int _maxScanLineSize;
  int _numScanLines;
  List<_PizChannelData> _channelData;
  Uint16List _tmpBuffer;
}

class _PizChannelData {
  int start;
  int end;
  int nx;
  int ny;
  int ys;
  int size;
}
