#!/usr/bin/env python

# IMPORTANT: the parameter (variable) names used in the web pages should be consistent to those used in Python and R.
# the above line is not need now, since a name map is used.

import sys, os #, MySQLdb, cPickle #, tempfile

import cgitb; cgitb.enable(display=0, logdir='/tmp')

from cgitools import *
from tools import decodeStr, encodeStr
from finishJob import convertImg, outputZip, tmp_exts, table_model, chart_model
import cPickle

# set mask for file
os.umask(6)
reqs = os.getenv('PATH_INFO')
if reqs: 
	req_id = decodeStr(reqs[1:])
	try: req_id = int(req_id)
	except: pass
else: 
	print cgi_token
	print '<p><input type="button" value="Go back" onClick="JavaScript:history.go(-1)"/>'
	sys.exit(0)

error_msg = []

#sql_statement = 'SELECT requests.req_state, requests.req_info, requests.error_msg, requests.category FROM requests, users WHERE users.user_name="%s" and users.id=requests.user_id and requests.req_name="%s"' % (username, req_id)
#sql_statement = 'SELECT requests.req_state, requests.req_info, requests.error_msg, requests.category FROM requests, users WHERE (users.user_name="demo" or users.user_name="%s") and users.id=requests.user_id and requests.req_name="%s"' % (username, req_id)

if type(req_id) is str: sql_statement = 'SELECT requests.req_name, requests.req_state, requests.req_info, requests.error_msg, requests.category FROM requests WHERE requests.req_name="%s"' % req_id
else: # int
	sql_statement = 'SELECT requests.req_name, requests.req_state, requests.req_info, requests.error_msg, requests.category FROM requests WHERE requests.req_id=%d' % req_id

req_id, req_state, req_info, error_info, category = inquireDB(sql_statement, fetch=True)[0]

req_info = cPickle.loads(req_info)

print cgi_token

print "<body bgcolor='white'>\n"
if req_state == STATE_ERROR:
	print error_info.replace('\n', '<p>')
	if category in TYPE_WEBARRAYDB_FILL: sys.exit(0)
	print '<table><tr><td height=60/></tr></table><p>'
	print "<a name = 'RESULT_TOP'><h1><center>Incomplete results of %s</center></h1>\n" % req_id
elif req_state == STATE_WORKING:
	print "<a name = 'RESULT_TOP'><h1><center>Preview results of %s</center></h1>\n" % req_id
else: # STATE_SOLVED or STATE_STOPPED
	print "<a name = 'RESULT_TOP'><h1><center>Results of %s</center></h1>\n" % req_id

if error_msg:
	print "<br>".join(error_msg),"<br>"
	sys.exit(0)
	

#import zipfile
output_zip = req_id+'_outputs.zip'

def rltHTML(req_id, result_dir, name_model = [], filetypes_excluded=tmp_exts): 
	# name_model is something like { 'normalized':'output.normalized.data.txt', 'result':'output.analyzed.data' }
	if not name_model: return
	filenames = os.listdir(result_dir)
	filenames.sort()

	#print "<p><a name = 'RESULT_TOP'></a>"
	#outputZip(result_dir) # now this is done in finishJob.py
	if req_state == STATE_STOPPED:
		outputZip(result_dir, req_id=req_id, req_type=category, override=False)
	
	zip_name = os.path.join(result_dir, output_zip)
	if os.path.exists(zip_name): 
		print "Please <a href='%s/saveFile?%s'>download</a> the result package (%s bytes) - a zip file including all result files." % (script_path_url, encodeStr(zip_name), os.stat(zip_name).st_size)

	name_start = 0 #len(req_id + '_')
	#if filenames and (filenames[0].find(req_id)==0): # for new reqs
	for nm_mdl in name_model:#.items():
		if len(nm_mdl) == 3:
			nm, mdl, vfun = nm_mdl
		else: # should be 2
			nm, mdl = nm_mdl 
			vfun = 'viewFile'
		#mdl = req_id + '_' + mdl
		fnms = filter(lambda a:(mdl in a) and (os.path.splitext(a)[1] not in filetypes_excluded), filenames)
		if not fnms: continue
		#print "<p><a name = 'RESULT_TOP'></a>"
		if len(fnms)==1:
			full_fn = encodeStr(os.path.join(result_dir, fnms[0]))
			save_fn = encodeStr(os.path.join(result_dir, fnms[0]) + os.sep + os.sep + req_id + '_' + fnms[0])
			print "<p>Please <a href='%s/%s?%s'>view</a> or <a href='%s/saveFile?%s'>download</a> the %s" % (script_path_url, vfun, full_fn, script_path_url, save_fn, nm)
		else:
			print "<p>Please view (or download) the %s data:" % nm
			for fn in fnms:
				full_fn = encodeStr(os.path.join(result_dir, fn))
				save_fn = encodeStr(os.path.join(result_dir, fn) + os.sep + os.sep + req_id + '_' + fn)
				print "<br>&nbsp;&nbsp;&nbsp;&nbsp;%s&nbsp;&nbsp;&nbsp;&nbsp;[<a href='%s/%s?%s'>view</a>]&nbsp;&nbsp;[<a href='%s/saveFile?%s'>download</a>]" % (fn, script_path_url, vfun, full_fn, script_path_url, save_fn)

def chartHTML_show_all_charts(graph_dir, chart_infos, name_start=0, filetypes_excluded=['.pdf', '.eps']):
	filenames = filter(lambda a:os.path.splitext(a)[1] not in filetypes_excluded, os.listdir(graph_dir))
	filenames.sort()
	if filenames:
		def fltFun(x):
			tk = x[0]
			s = x[1]
			if type(tk) is str: return tk in s
			return tk.search(s) # should be a re object
		# print content list
		print '<p><table ><tr><th><b>Charts:</b></th><tr><td><ul>'
		#for k in chart_names: #k,v in chart_infos.items():
		for k, v in chart_infos: #k,v in chart_infos.items():
			#v = chart_infos[k]
			#if 'files' not in v: v['files'] = filter(lambda a:(v['token'] in a[name_start:]), filenames)
			#if not v.get('files',None): v['files'] = filter(lambda a:(v['token'] in a[name_start:]), filenames)
			if not v.get('files',None): v['files'] = filter(lambda a:fltFun((v['token'], a[name_start:])), filenames)
			if v['files']: print '<li><a href=#%s>' % k.replace('.','_'), v['comment'], '</a>'
		print '</ul></td></table>'
		# print charts
		print '<p><ul>'
		for k in chart_names: #k,v in chart_infos.items():
			v = chart_infos[k]
			if v['files']:
				#v_show = map(lambda a:os.path.splitext(a)+(a,), v['files'])
				#v_show = map(lambda a:a[1]=='.pdf' and (a[0]+'.eps') or a[2], v_show) # change the name .pdf to .eps
				v_show = v['files'][:]
				v_legend = v.get('legend', '')
				if v_legend: v_show[0] = '%s<br><font size=-1>%s</font>' % (v_show[0], v_legend)
				print '<table><tr><td height=40 /></tr></table><br><li><font size=+1><b><a name=%s></a>' % k.replace('.', '_'), v['comment'], ' <a href=#RESULT_TOP>(return TOP)</a></b></font>'
				#chart_urls = zip(map(lambda a:path2url(os.path.join(graph_dir,a)), v['files']), v['files'])
				#print '<br><table>', reduce(lambda a,b:a+('<tr><td align=center><img src="%s"></td></tr><tr><td align=center>%s</td></tr><tr><td height=20></td></tr>' % b), chart_urls, ''), '</table>'
				#chart_urls = zip(map(lambda a:encodeStr(os.path.join(graph_dir,a)), v['files']), v['files'])
				chart_urls = zip(map(lambda a:encodeStr(os.path.join(graph_dir,a)), v['files']), v_show)
				print '<br><table>', reduce(lambda a,b:a+('<tr><td align=center><img src="%s/showImage?%s"></td></tr><tr><td align=center>%s</td></tr><tr><td height=20></td></tr>\n' % ((script_path_url,) + b) ), chart_urls, ''), '</table>'
		print '</ul>'

jsfuncs = '''
<script type='text/javascript' language='javascript'>
var script_url = "%s";
function showMoreCharts(thetd, chts, pths) {
	thetd.innerHTML = '' //thetd.removeChild(btn)
	var thetr = thetd.parentNode
	var thetb = thetr.parentNode
	var blanktr = thetr.nextSibling
	var newtr, tmptr = thetr.cloneNode(true)
	thetd.innerHTML = '<img src="' + script_url + '/showImage?' + pths[0] + '">'
	newtr = tmptr.cloneNode(true)
	newtr.firstChild.innerHTML = chts[0]
	thetb.insertBefore(newtr, blanktr)

	for (var i=1; i<chts.length; i++) {
		newtr = tmptr.cloneNode(true)
		newtr.firstChild.innerHTML = '<img src="' + script_url + '/showImage?' + pths[i] + '">'
		thetb.appendChild(newtr)
		newtr = tmptr.cloneNode(true)
		newtr.firstChild.innerHTML = chts[i]
		thetb.appendChild(newtr)
		thetb.appendChild(blanktr.cloneNode(true))
		}
	}
</script>
''' % (script_path_url, )

#def chartHTML(graph_dir, chart_names, chart_infos, name_start=0, filetypes_excluded=['.pdf', '.eps'], sect_max=5):
def chartHTML(graph_dir, chart_infos, name_start=0, filetypes_excluded=['.pdf', '.eps'], sect_max=5):
	filenames = filter(lambda a:os.path.splitext(a)[1] not in filetypes_excluded, os.listdir(graph_dir))
	filenames.sort()
	if filenames:
		def fltFun(x):
			tk = x[0]
			s = x[1]
			if type(tk) is str: return tk in s
			return tk.search(s) # should be a re object
		# print content list
		print jsfuncs
		print '<p><table ><tr><th><b>Charts:</b></th><tr><td><ul>'
		#for k in chart_names: #k,v in chart_infos.items():
		for k, v in chart_infos: #k,v in chart_infos.items():
			#v = chart_infos[k]
			#if 'files' not in v: v['files'] = filter(lambda a:(v['token'] in a[name_start:]), filenames)
			#if not v.get('files',None): v['files'] = filter(lambda a:(v['token'] in a[name_start:]), filenames)
			if not v.get('files',None): v['files'] = filter(lambda a:fltFun((v['token'], a[name_start:])), filenames)
			if v['files']: print '<li><a href=#%s>' % k.replace('.','_'), v['comment'], '</a>'
		print '</ul></td></table>'
		# print charts
		print '<p><ul>'
		#for k in chart_names: #k,v in chart_infos.items():
		for k, v in chart_infos: #k,v in chart_infos.items():
			#v = chart_infos[k]
			if v['files']:
				#v_show = map(lambda a:os.path.splitext(a)+(a,), v['files'])
				#v_show = map(lambda a:a[1]=='.pdf' and (a[0]+'.eps') or a[2], v_show) # change the name .pdf to .eps
				v_show = v['files'][:sect_max]
				v_legend = v.get('legend', '')
				if v_legend: v_show[0] = '%s<br><font size=-1>%s</font>' % (v_show[0], v_legend)
				print '<table><tr><td height=40 /></tr></table><br><li><font size=+1><b><a name=%s></a>' % k.replace('.', '_'), v['comment'], ' <a href=#RESULT_TOP>(return TOP)</a></b></font>'
				#chart_urls = zip(map(lambda a:path2url(os.path.join(graph_dir,a)), v['files']), v['files'])
				#print '<br><table>', reduce(lambda a,b:a+('<tr><td align=center><img src="%s"></td></tr><tr><td align=center>%s</td></tr><tr><td height=20></td></tr>' % b), chart_urls, ''), '</table>'
				#chart_urls = zip(map(lambda a:encodeStr(os.path.join(graph_dir,a)), v['files']), v['files'])
				if len(v['files']) > sect_max:
					btnstr = '''<tr><td align=center><input type=button value='Show all %d charts' onClick='javascript:showMoreCharts(this.parentNode, ["%s"], ["%s"])'></td></tr><tr><td height=20></td></tr>\n''' % (len(v['files']), '","'.join(v['files'][sect_max:]), '","'.join(map(lambda a:encodeStr(os.path.join(graph_dir,a)), v['files'][sect_max:])) )
				else: btnstr = ''
				chart_urls = zip(map(lambda a:encodeStr(os.path.join(graph_dir,a)), v['files'][:sect_max]), v_show)
				print '<br><table>', reduce(lambda a,b:a+('<tr><td align=center><img src="%s/showImage?%s"></td></tr><tr><td align=center>%s</td></tr><tr><td height=20></td></tr>\n' % ((script_path_url,) + b) ), chart_urls, ''), btnstr, '</table>'
		print '</ul>'

def convertPDF(path, keep=True):
	# convert PDF to eps
	if req_state == STATE_STOPPED:
		convertImg(path, src='.pdf', obj=['.png', '.eps'])
	return # now this is done by finishJob.py
	cwd = os.getcwd()
	os.chdir(path)
	fns_all = os.listdir('.')
	fns = filter(lambda a:a[-4:]=='.pdf', fns_all)
	fns = map(lambda a:(a, a[:-4]+'.eps', a[:-4]+'.png'), fns)
	#os.system('for nm in *.pdf; do gs -sDEVICE=epswrite -sOutputFile="${nm%pdf}eps" -q "${nm}" -c quit; done; rm -rf *.pdf;')
	prog = sys.platform == 'win32' and 'gswin32c' or 'gs'
	for fpdf, feps, fpng in fns:
		try:
			if feps not in fns_all: os.popen('%s -q -sDEVICE=epswrite -sOutputFile="%s" "%s" -c quit' % (prog, feps, fpdf), 'r').read()
			if fpng not in fns_all: os.popen('%s -q -sDEVICE=png256 -sOutputFile="%s" "%s" -c quit' % (prog, fpng, fpdf), 'r').read()
			if not keep: os.unlink(fpdf) #os.system('rm "%s"' % fpdf)
		except: pass
	os.chdir(cwd)

if category == TYPE_NORM_ANALYSIS or category==TYPE_LINEAR_DUAL or category==TYPE_LINEAR_AFFY:
	if category == TYPE_NORM_ANALYSIS or category==TYPE_LINEAR_DUAL:
		chart_infos = chart_model[TYPE_NORM_ANALYSIS]
	else: # must be TYPE_LINEAR_AFFY
		chart_infos = chart_model[TYPE_LINEAR_AFFY]
	table_infos = table_model[TYPE_NORM_ANALYSIS]
	result_dir = req_info['result.data.dir']
	graph_dir = req_info['chart.dir']
	if not os.path.exists(graph_dir): graph_dir = os.path.join(result_dir, relative_chart_dir) # for old requests
	convertPDF(graph_dir)
	rltHTML(req_id, result_dir, table_infos)
	name_start = 0 #len(req_id+'_')
	chartHTML(graph_dir, chart_infos, name_start=name_start)
elif category == TYPE_NORMPCA:
	chart_infos = chart_model[TYPE_NORMPCA]
	result_dir = req_info['output_dir']
	
	if not os.path.exists(result_dir): result_dir = os.path.join(users_dir, username, relative_result_dir, req_id) # for old requests
	result_file = os.path.join(result_dir, 'normalized_by_pca.txt')
	result_file_url = path2url(result_file)
	graph_dir = req_info['chart_dir']
	if not os.path.exists(graph_dir): graph_dir = os.path.join(result_dir, relative_chart_dir) # for old requests
	#for k in chart_infos.keys(): 
	for k, v in chart_infos: 
		full_name = os.path.join(graph_dir, k)
		#chart_infos[k]['full'] = full_name
		v['full'] = full_name
		if os.path.exists(full_name): v['exist'] = True
		else: v['exist'] = False
		
	convertPDF(graph_dir)
	rltHTML(req_id, result_dir, table_model[TYPE_NORMPCA])
	print '<p><table><tr><th><b>Charts:</b></th><tr><td><ul>'
	for k,v in chart_infos: #.items(): 
		if v['exist']: print '<li><a href=#%s>' % k.replace('.','_'), v['comment'], '</a>'
	print '</ul></td></table><p><ul>'
	for k,v in chart_infos: #.items():
		if v['exist']:
			print '<li><font size=+1><b><a name=%s></a>' % k.replace('.', '_'), v['comment'], ' <a href=#RESULT_TOP>(return TOP)</a></b></font>'
			print '<br><table><tr><td align=center><img src="%s"></td><tr><td align=center>%s</td>' % (path2url(v['full']), k), '</table>'
	print '</ul>'
elif category in TYPE_SHOW_ERR:
	print error_info and error_info.replace('\n', '<p>') or 'No information to present.'
	print '<p><input type="button" value="Go back" onClick="JavaScript:history.go(-1)"/>'

elif category == TYPE_DBS_ANALYSIS:
	graph_dir = os.path.join(req_info['result_dir'], 'chart')
	convertPDF(graph_dir)
	rltHTML(req_id, req_info['result_dir'], table_model[TYPE_DBS_ANALYSIS])

	name_start = 0 #len(req_id+'_')
	chartHTML(graph_dir, chart_model[TYPE_DBS_ANALYSIS], name_start=name_start)

else: # different result display
	pass

print "</body>"


