#!/usr/bin/python

'''
Copyright 2013 Google Inc.

Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
'''


from __future__ import print_function
import math
import pprint


def withinStdDev(n):
  """Returns the percent of samples within n std deviations of the normal."""
  return math.erf(n / math.sqrt(2))


def withinStdDevRange(a, b):
  """Returns the percent of samples within the std deviation range a, b"""
  if b < a:
    return 0;

  if a < 0:
    if b < 0:
      return (withinStdDev(-a) - withinStdDev(-b)) / 2;
    else:
      return (withinStdDev(-a) + withinStdDev(b)) / 2;
  else:
    return (withinStdDev(b) - withinStdDev(a)) / 2;


# We have some smudged samples which represent the average coverage of a range.
# We have a 'center' which may not line up with those samples.
# From center make a normal where 5 sample widths out is at 3 std deviations.
# The first and last samples may not be fully covered.

# This is the sub-sample shift for each set of FIR coefficients
#   (the centers of the lcds in the samples)
# Each subpxl takes up 1/3 of a pixel,
#   so they are centered at x=(i/n+1/2n), or 1/6, 3/6, 5/6 of a pixel.
# Each sample takes up 1/4 of a pixel,
#   so the results fall at (x*4)%1, or 2/3, 0, 1/3 of a sample.
samples_per_pixel = 4
subpxls_per_pixel = 3
#sample_offsets is (frac, int) in sample units.
sample_offsets = [
  math.modf(
    (float(subpxl_index)/subpxls_per_pixel + 1.0/(2.0*subpxls_per_pixel))
    * samples_per_pixel
  ) for subpxl_index in range(subpxls_per_pixel)
]

#How many samples to consider to the left and right of the subpxl center.
sample_units_width = 5

#The std deviation at sample_units_width.
std_dev_max = 3

#The target sum is in some fixed point representation.
#Values larger the 1 in fixed point simulate ink spread.
target_sum = 0x110

for sample_offset, sample_align in sample_offsets:
  coeffs = []
  coeffs_rounded = []

  #We start at sample_offset - sample_units_width
  current_sample_left = sample_offset - sample_units_width
  current_std_dev_left = -std_dev_max

  done = False
  while not done:
    current_sample_right = math.floor(current_sample_left + 1)
    if current_sample_right > sample_offset + sample_units_width:
      done = True
      current_sample_right = sample_offset + sample_units_width
    current_std_dev_right = current_std_dev_left + (
      (current_sample_right - current_sample_left) / sample_units_width
    ) * std_dev_max

    coverage = withinStdDevRange(current_std_dev_left, current_std_dev_right)
    coeffs.append(coverage * target_sum)
    coeffs_rounded.append(int(round(coverage * target_sum)))

    current_sample_left = current_sample_right
    current_std_dev_left = current_std_dev_right

  # Have the numbers, but rounding needs to add up to target_sum.
  delta = 0
  coeffs_rounded_sum = sum(coeffs_rounded)
  if coeffs_rounded_sum > target_sum:
    # The coeffs add up to too much.
    # Subtract 1 from the ones which were rounded up the most.
    delta = -1

  if coeffs_rounded_sum < target_sum:
    # The coeffs add up to too little.
    # Add 1 to the ones which were rounded down the most.
    delta = 1

  if delta:
    print("Initial sum is 0x%0.2X, adjusting." % (coeffs_rounded_sum,))
    coeff_diff = [(coeff_rounded - coeff) * delta
                  for coeff, coeff_rounded in zip(coeffs, coeffs_rounded)]

    class IndexTracker:
      def __init__(self, index, item):
        self.index = index
        self.item = item
      def __lt__(self, other):
        return self.item < other.item
      def __repr__(self):
        return "arr[%d] == %s" % (self.index, repr(self.item))

    coeff_pkg = [IndexTracker(i, diff) for i, diff in enumerate(coeff_diff)]
    coeff_pkg.sort()

    # num_elements_to_force_round better be < (2 * sample_units_width + 1) or
    # * our math was wildy wrong
    # * an awful lot of the curve is out side our sample
    # either is pretty bad, and probably means the results will not be useful.
    num_elements_to_force_round = abs(coeffs_rounded_sum - target_sum)
    for i in xrange(num_elements_to_force_round):
      print("Adding %d to index %d to force round %f." % (
          delta, coeff_pkg[i].index, coeffs[coeff_pkg[i].index]))
      coeffs_rounded[coeff_pkg[i].index] += delta

  print("Prepending %d 0x00 for allignment." % (sample_align,))
  coeffs_rounded_aligned = ([0] * int(sample_align)) + coeffs_rounded

  print(', '.join(["0x%0.2X" % coeff_rounded
                   for coeff_rounded in coeffs_rounded_aligned]))
  print(sum(coeffs), hex(sum(coeffs_rounded)))
  print()
