import csv
import os
import shutil

from gavo import api
from gavo.utils import fitstools
from gavo.helpers import fitstricks
from gavo.utils import pyfits, hmsToDeg, dmsToDeg
from datetime import datetime, timedelta

RD = api.getRD("plts/q")

def addObsCards(srcName, origHeader):

	
	return res


# Things I varied: DETECT_THRESH: 6..20, BACK_FILTERSIZE 3x3/10x10
class PlsAnetProcessor(api.AnetHeaderProcessor):
	sexControl = """DETECT_THRESH  6
		SEEING_FWHM      1.2
		WEIGHT_TYPE BACKGROUND
		BACK_SIZE 20
		BACK_FILTERSIZE 3x3
		DETECT_TYPE CCD
		MEMORY_PIXSTACK 8000000
		MEMORY_OBJSTACK 8000
		MEMORY_BUFSIZE 2048
		"""
	sp_plots = False
#	sp_indices = ["index-4211.fits", "index-4210.fits",
#		"index-4209.fits", "index-4208.fits"]
	sp_indices = ["index-211.fits", "index-210.fits",
		"index-209.fits", "index-208.fits"]
	sp_total_timelimit = 320
	sp_endob = 50

	def _createAuxiliaries(self, dd):
		with open(dd.rd.getAbsPath("docs/plate-combined.txt")) as f:
			self.metadata = {m["platenum"]: m for m in
				csv.DictReader(f, [
				 "platenum", "start_time", "exposure", "flag", "coords",
				 "obsnotes", "emulsion"])}

	def classify(self, srcName):
		if os.path.exists(srcName+".hdr"):
			return "calibrated"
		return "uncalibrated"

	def objectFilter(self, inName):
		"""throws out funny-looking objects from inName and throws out objects
		near the border.
		"""
		hdulist = pyfits.open(inName)
		data = hdulist[1].data
		width = max(data.field("X_IMAGE"))
		height = max(data.field("Y_IMAGE"))
		badBorder = 0.07
		data = data[data["ELONGATION"]<1.2]
		data = data[data["X_IMAGE"]>width*badBorder]
		data = data[data["X_IMAGE"]<width-width*badBorder]
		data = data[data["Y_IMAGE"]>height*badBorder]
		data = data[data["Y_IMAGE"]<height-height*badBorder]
		if len(data)==0:
			raise api.CannotComputeHeader("No objects left after cleanup?")
		hdu = pyfits.BinTableHDU(data)
		hdu.writeto("foo.xyls")
		hdulist.close()
		os.rename("foo.xyls", inName)

	def _isProcessed(self, srcName):
		return False

	def _getHeader(self, srcName):
		origHeader = api.AnetHeaderProcessor._getHeader(self, srcName)

		for junkCard in ["DISPERS", "MULTIEXP", "PRISMANG", "RA", "DEC",
				"INVERTED", "WFPDB-ID"]:
			if junkCard in origHeader:
				del origHeader[junkCard]

		vals = fitstricks.getHeaderAsDict(origHeader)

		platenum, platepart = os.path.splitext(
			os.path.basename(srcName))[0].split("_")
		metadata = self.metadata[platenum]

		xpixsz = ypixsz = 0.0141 # pixel size in mm, 1800 dpi scan resolution
		focallen = 3067

		day, fract = metadata["start_time"].split(".")
		dateObs = datetime.strptime(day, "%Y %m %d"
			)+timedelta(days=float("." + str(fract or 0)))
		telscale = 360*abs(float(origHeader["CD1_1"]))/xpixsz

		# see paper page 3
		# those values seems to be a reasonable default, according to raw docs
		if float(metadata["exposure"]) > 20:
			filter = "Y-6"
			emulsion = "103a-D"
		else:
			filter = "WG-2"
			emulsion = "103a-O"
		
		if metadata["emulsion"]:
			emulsion = metadata["emulsion"]
		exposureSec = float(metadata["exposure"])*60

		try:
			ra_orig = hmsToDeg(metadata["coords"][:11])
			dec_orig = dmsToDeg(metadata["coords"][12:])
		except ValueError:
			ra_orig = hmsToDeg(metadata["coords"][:9])
			dec_orig = dmsToDeg(metadata["coords"][10:])
	
		assert len(platenum)==5

		vals.update({
			### Group 2 - original data of the observation
			"DATEORIG": metadata["start_time"].replace(" ", "-"), # TODO: seconds?
			"RA_ORIG": ra_orig,
			"DEC_ORIG": dec_orig,
			"OBJECT": "Trojan",
			"OBJTYP": "Asteroid",
			"EXPTIME": exposureSec,
			"NUMEXP": 1,
			"OBSERVAT": "Palomar Observatory",
			"SITELAT": 33.356389,
			"SITELONG": -116.865,
			"SITEELEV": 1702,
			"TELESCOP": "122cm Palmor Schmidt",
			"TELAPER": 1.22,
			"TELFOC": float(focallen) / 1000.0,
			"TELSCALE": telscale,
			"INSTRUME": "48-inch Schmidt camera",
			"DETNAM": "Photographic Plate",
			"FILTER": filter,
			"OBSERVER": "T. Gehrels",
			"PRISMANG": None,
			"DISPERS": None,
			### Group 3 - information about the photographic plate
			"PLATENUM": platenum,
			"SERIES": "Palomar-Leiden Trojan Survey",
			"PLATEFMT": "35.6x35.6",
			"PLATESZ1": xpixsz * vals["NAXIS1"]/10,
			"PLATESZ2": ypixsz * vals["NAXIS2"]/10,
			"FOV1": abs(vals["CD1_1"]) * vals["NAXIS1"],
			"FOV2": abs(vals["CD2_2"]) * vals["NAXIS2"],
			"EMULSION": emulsion,
			"PLATNOTE": metadata["obsnotes"],
			###
			"SCANRES1": vals["SCANRES"],
			"SCANRES2": vals["SCANRES"],
			### Group 4 - computed data of the observation
			"DATE_OBS": dateObs.strftime('%Y-%m-%dT%H:%M:%S'),
			"DATE_AVG": (dateObs + timedelta(
				seconds = exposureSec / 2.0 )
			).strftime('%Y-%m-%dT%H:%M:%S'),
			"DATE_END": (dateObs + timedelta(
				seconds = exposureSec)
			).strftime('%Y-%m-%dT%H:%M:%S'),
			"YEAR": dateObs.year,
			"JD": api.dateTimeToJdn(dateObs),
			"PIXSIZE1": xpixsz*1000.0, # mm -> um
			"PIXSIZE2": ypixsz*1000.0, # mm -> um
			"ORIGIN": "GAVO DC, plts/bin/calibrate.py",
			"FLAG": metadata["flag"],
			"WFPDB_ID": "PAL122 6a0%s"%platenum,
		})

		newHeader = fitstricks.makeHeaderFromTemplate(fitstricks.WFPDB_TEMPLATE,
			originalHeader=origHeader, **vals)

		newHeader.set("PLATPART", platepart,
			comment="2 scans per plate (plate>scanner)",
			after="PLATENUM")

		return newHeader

if __name__=="__main__":
	api.procmain(PlsAnetProcessor, "plts/q.rd", "import")
