#!/usr/bin/python

import sys, os
import re
import time
import math
#import Image, ImageOps, ImageDraw, ImageFont

SRCDIRBASE = '../../../work/jmbsc/mtsat/'

now = time.strptime(sys.argv[1],'%Y%m%d%H')
obstart = time.mktime(now) - 3600 # observation -30min
gmt = time.localtime(obstart)
nomtime = time.localtime(obstart + 3600) # 1hour
srcdir = SRCDIRBASE + time.strftime('%Y%m%d', gmt) + '/'
srcbase = 'Z__C_RJTD_%4d%02d%02d%02d????_OBS_SAT_Pir%s_R%sh_image.tar.gz'

def untar(gmt, ch):
    b = list(gmt)[:4]
    b.append(ch)
    d = b + ['n']
    cmd = 'tar xvzf %s' % srcdir + srcbase % tuple(d)
    t = os.popen(cmd, 'r')
    files1 = t.read().splitlines()
    t.close()
    d = b + ['s']
    cmd = 'tar xvzf %s' % srcdir + srcbase % tuple(d)
    t = os.popen(cmd, 'r')
    files2 = t.read().splitlines()
    t.close()
    return files1 + files2

def skipheader(fi):
    while 1:
        a = fi.read(1)
        b = ord(fi.read(1))*256 + ord(fi.read(1))
        c = fi.read(b-3)
        if ord(a) == 132:
            break

def readtype(fi):
    type = ord(fi.read(1))
    bytes = ord(fi.read(1))*256 + ord(fi.read(1))
    content = fi.read(bytes-3)
    return type, bytes, content

def int4(s):
    x = 0
    for i in s:
        x = x * 256 + ord(i)
    return x

def getnav(fi):
    # skip #0,#1 header
    type, bytes, content = readtype(fi)
    type, bytes, content = readtype(fi)
    type, bytes, content = readtype(fi)
    assert type == 2
    sub_lon = re.match(r'GEOS\((.*)\)', content).group(1)
    sub_lon = float(sub_lon)
    CFAC = float(int4(content[32:36]))/(2**16)
    LFAC = float(int4(content[36:40]))/(2**16)
    COFF = int4(content[40:44])
    LOFF = int4(content[44:48])
    # print COFF, LOFF, CFAC, LFAC, sub_lon
    return sub_lon, CFAC, LFAC, COFF, LOFF

''' Commented out by triple-singlequote
    ## These functions are coded in C
def topgm(files):
    foname = files[0][:-2] + '.pgm'
    fo = file(foname, 'w')
    print >> fo, """P5
2750 2750
255"""
    for f in files:
        fi = file(f)
        skipheader(fi)
        for i in xrange(2750*275):
            a = ord(fi.read(1))
            b = ord(fi.read(1))
            x = ((a << 6) & 0xc0) | ((b >> 2) & 0x3f)
            fo.write(chr(x))
        fi.close()
    fo.close()
    return foname
'''

# conversion parameters
degree = math.pi / 180.
radian = 1./degree

'''
def geos(lon, lat):
    # return (col, line) numbers
    # inputs are in degree
    c_lat = math.atan(0.993243 * math.tan(lat*degree))
    rl = 6356.5838/math.sqrt(1-0.00675701*math.cos(c_lat)**2)
    r1 = 42164.-rl*math.cos(c_lat)*math.cos((lon-sub_lon)*degree)
    r2 = -rl*math.cos(c_lat)*math.sin((lon-sub_lon)*degree)
    r3 = rl*math.sin(c_lat)
    rn = math.sqrt(r1**2 + r2**2 + r3**2)
    x = math.atan(-r2/r1) * radian
    y = math.asin(-r3/rn) * radian
    c = COFF + int(x*CFAC+0.5)
    l = LOFF + int(y*LFAC+0.5)
    return c,l

def geotrans(imgfile, box, size):
    # imgfile ... original image file IMG_...pgm
    # box ....... lon_tl, lat_tl, lon_br, lat_br
    # size ...... width, height in pixel
    lon_tl, lat_tl, lon_br, lat_br = box
    width, height = size
    lat_inc = float(lat_br - lat_tl)/height
    lon_inc = float(lon_br - lon_tl)/width
    img = Image.open(imgfile)
    imgdata = list(img.getdata())
    oimgdata = []
    for y in xrange(height):
        lat = lat_tl + lat_inc * y
        for x in xrange(width):
            lon = lon_tl + lon_inc * x
            c, l = geos(lon, lat)
            oimgdata.append(imgdata[l*img.size[0]+c])
    oimg = Image.new('L', size)
    oimg.putdata(oimgdata)
    return oimg

def writegame(img, box, size, ch):
    lon_tl, lat_tl, lon_br, lat_br = box
    width, height = size
    lat_inc = float(lat_br - lat_tl)/height
    lon_inc = float(lon_br - lon_tl)/width
    fname = 'MT1R%02d%02d%02d%02dIR%d.pgm' % (
               nomtime[0]%100, nomtime[1], nomtime[2], nomtime[3], ch)
    fo = file(fname, 'w')
    print >> fo, """P5
#N%dN%dE%dE%d %5.3f %5.3f
%d %d
255""" % (lat_tl, lat_br, lon_tl, lon_br, -lat_inc, lon_inc, size[0], size[1])
    imgdata = list(img.getdata())
    imgstr = ''.join(
                  [chr(imgdata[i]) for i in xrange(img.size[0]*img.size[1])])
    fo.write(imgstr)
    fo.close()
    os.system('gzip %s' % fname)
    return fname+'.gz'
'''

def proc(ch):
    global sub_lon, CFAC, LFAC, COFF, LOFF
    files = untar(gmt, ch)
    ### mtname = topgm(files)
    os.system('./topgm ' + ' '.join(files))
    mtname = files[0][:-2] + '.pgm'
    sub_lon, CFAC, LFAC, COFF, LOFF = getnav(file(files[4]))
    navargs = '%d %d %f %f %f' % (COFF, LOFF, CFAC, LFAC, sub_lon)
    fname = 'MT1R%02d%02d%02d%02dIR%d.pgm' % (
             nomtime[0]%100, nomtime[1], nomtime[2], nomtime[3], ch)
    args = ' '.join([ mtname, fname, '70 70 160 -20 1800 1800', navargs ])
    os.system('./geosgame %s' % args)
    os.system('gzip %s' % fname)
    ### game = geotrans(mtname, (70,70,160,-20), (1800,1800))
    ### fname = writegame(game, (70,70,160,-20), (1800,1800), ch)
    os.system('rm -f IMG*')

if __name__ == '__main__':
    for ch in range(1,5):
        proc(ch)
