#=======================================================================
# Author: Donovan Parks
#
# Look up critical value for studentized range distribution.
#
# Copyright 2011 Donovan Parks
#
# This file is part of STAMP.
#
# STAMP is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# STAMP is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with STAMP.	If not, see <http://www.gnu.org/licenses/>.
#=======================================================================

import os

import math

class QTable():
	def __init__(self, preferences):
		CVs = ['0.001', '0.01', '0.02', '0.05', '0.1']
		tables = ['tukeyQ_001.txt', 'tukeyQ_01.txt', 'tukeyQ_02.txt', 'tukeyQ_05.txt', 'tukeyQ_10.txt']
		
		self.qTables = {}
		for i in xrange(0, len(tables)):
			dataPath = os.path.join(os.path.split(os.path.realpath(__file__))[0], '..', '..', '..', 'data', tables[i])
			
			fin = open(dataPath, 'U')
			data = fin.readlines()
			fin.close()
			
			qTable = {}
			for j in xrange(1, len(data)):
				lineSplit = data[j].split('\t')
				values = [float(x) for x in lineSplit[1:]]
				qTable[j+1] = values
				
			self.qTables[CVs[i]] = qTable
			
			
	def cv(self, alpha, k, df):
		if k < 2 or df < 2:
			return 1000.0
			
		if k > 30:
			k = 30	# reasonable approximation to infinity, should perhaps issue a warning here though
			
		if df > 200:
			df = 200	# this is a good approximation to infinity
			
		alphaStr = '%.3g' % alpha
		return self.qTables[alphaStr][df][k-2]	# table starts at k=2
		
	def cvInterpolate(self, alpha, k, df):

		dfLower = int(math.floor(df))
		dfUpper = int(math.ceil(df))
		
		cvLower = self.cv(alpha, k, dfLower)
		cvUpper = self.cv(alpha, k, dfUpper)
		
		cv = cvLower + (df-dfLower)*(cvUpper-cvLower)
		
		return cv
			