#!/usr/bin/env python

import sys
import time

import numpy as np

from optparse import OptionParser

import progressbar

import interp.bootstrap

from   interp.grid.gmsh     import ggrid
from   interp.grid.delaunay import dgrid

from   interp.tools         import improved_answer
from   interp.tools         import baker_exact_2D, baker_exact_3D
from   interp.tools         import friendly_exact_2D, friendly_exact_3D

def get_right_exact_func(options):
  f = None
  if options.dimension == 3:
    if options.baker:
      f = baker_exact_3D
    else:
      f =friendly_exact_3D
  elif options.dimension == 2:
    if options.baker:
      f = baker_exact_2D
    else:
      f = friendly_exact_2D
  return f

if __name__ == '__main__':

  parser = OptionParser(usage = "%prog [options] <input file (gmsh) or random grid count (delaunay)> <number of attempts>")

  parser.add_option("-v", "--verbose",
    action="store_true", dest="verbose", default=False,
    help="verbose flag")

  parser.add_option("-b", "--baker",
    action="store_true", dest="baker", default=False,
    help="use more impressive baker funcs")

  meshtype_options = ('gmsh', 'delaunay')
  parser.add_option('-t', '--type',
    type="str", dest="meshtype", default='delaunay',
    help="specify mesh type (default: %default, options gmsh, delaunay)")

  parser.add_option("-d", "--dimension",
    type="int", dest="dimension", default=3,
    help="use 3D or 2D gmsh lib (default: %default)")

  parser.add_option("-o", "--order",
    type="int", dest="order", default=3,
    help="order of interpolation (default: %default)")

  parser.add_option("-e", "--extra-points",
    type="int", dest="extra", default=3,
    help="number of extra points (default: %default)")


  (options, args) = parser.parse_args()
  if len(args) != 2:
    parser.print_usage()
    sys.exit(1)

  input_file, count = args
  count = int(count)

  if options.meshtype == 'gmsh':
    g = ggrid(input_file, options.dimension)
  elif options.meshtype == 'delaunay':
    point_count = int(input_file)
    v = np.random.random((point_count, options.dimension))
    g = dgrid(v)
  else:
    raise Exception("improper mesh type specified. options: %s\n%s" % (str(meshtype_options), options.meshtype))

  g.q = np.array([get_right_exact_func(options)(x) for x in g.verts])

  results = {True:0, False:0}
  i = 0
  outside = 0
  pbar = progressbar.ProgressBar().start()
  start = time.time()
  while i < count:
    try:
      X = np.random.random((1,options.dimension))[0]

      a = g.run_baker(X, order = options.order, extra_points = options.extra)
      e = get_right_exact_func(options)(X)

      results[improved_answer(a, e)] += 1
      update = i/float(count) * 100
      pbar.update(update)
      i += 1
    except Exception as e:
      # print e
      # print X, i, count
      outside += 1

  pbar.finish()
  end = time.time()
  print "total skipped points: %d" % outside
  print results, end - start
