import math

try:
    from mod_python import apache, util
except:
    print 'Cannot import from mod_python'

from urlparse import urlparse, parse_qs
import os
from string import Template
import datetime
import schemas

from catalog import WebDatabase

class Page():
    '''SADCAT web-page generator'''
    projects = {'maires': ['ANY',
                            'RADARSAT2',
                            'LANDSAT',
                            'ASAR',
                            'MERIS',
                            'NTSOMZ-RO2MSUE',
                            'NTSOMZ-RO3MSUE',
                            'NTSOMZ-RO4MSUE',
                            'NTSOMZ-M3MMSUE',
                            'NTSOMZ-OO1MSUSK',
                            'NTSOMZ-MEPSA',
                            'NTSOMZ-MERDSA',
                            'NTSOMZ-MM1KMSS',
                            'NTSOMZ-MM1BRLK',
                            ]
                }

    def __init__(self, req, mainTemplate):
        '''Constructor
            get project name
            get catalogs
            set project catalogs
            create empty dict htmlData
        '''
        self.reqData = util.FieldStorage(req, keep_blank_values=True)
        project = self.reqData.get('project', None)
        if project in self.projects:
            proCats = self.projects[project]
            self.cats = {}
            for cat in proCats:
                self.cats[cat] = schemas.cats[cat]
        else:
            self.cats = schemas.cats
            
        self.curdir = os.path.dirname(os.path.realpath(__file__))
        self.htmlTmp = self.read_header(os.path.join(self.curdir, mainTemplate))
            
        self.htmlData = dict()

    def read_header(self, fileName):
        '''Read HTML header from html-file'''
        f = open(fileName)
        html = Template(f.read())
        f.close()
        return html
        
    def set_params(self, req):
        '''Set defaults of the Page object based on input from POST or GET '''
        # set project specific header
        project = self.reqData.get('project', None)
        proHeaderHTML = ''
        if project is not None:
            proHeaderName = os.path.join(self.curdir, project + '_header.html')
            if os.path.exists(proHeaderName):
                proHeaderHTML = self.read_header(proHeaderName).template
                #req.write(proHeaderHTML)
        self.htmlData['HEADER_TITLE'] = proHeaderHTML
        
        yesterday = (datetime.date(1,1,1).today() - datetime.timedelta(1)).strftime('%Y-%m-%d')
        today = datetime.date(1,1,1).today().strftime('%Y-%m-%d')
        self.htmlData['START_DATE'] = self.reqData.get('date1', yesterday)
        self.htmlData['END_DATE'] = self.reqData.get('date2', today)
        self.htmlData['SCRIPT_URL'] = req.uri
        
        optionTemplate = '<option value=%s %s>%s</option>\n'
       
        # create seasons selector
        seasons = ['any', 'winter', 'spring', 'summer', 'autumn']
        curSeason = self.reqData.get('season', 'any')
        seasHtml = ''
        for season in seasons:
            sel = ''
            if season == curSeason:
                sel = 'selected=selected'
            seasHtml += optionTemplate % (season, sel, season)
        self.htmlData['SELECT_SEASON'] = seasHtml
        
        # create catalogs selector
        catsHtml = ''
        curCat = self.reqData.get('catalog', 'ANY')
        cats = self.cats.keys()
        cats.sort()
        for cat in cats:
            sel = ''
            if cat == curCat:
                sel = 'selected=selected'
            catsHtml += optionTemplate % (cat, sel, cat)
        self.htmlData['SELECT_CATALOG'] = catsHtml
        
        self.htmlData['INPUT_DBMASK'] = self.reqData.get('db_mask', '%')
        
        # create list of latlongs
        latlons = self.reqData.get('latlons', '')
        if len(latlons) > 0:
            latlons = latlons.replace('[','|').replace(']','|').replace(',','|').replace(' ','|')
            latlons = latlons.split('|')
            latlons2 = []
            for ll in latlons:
                if len(ll) > 0:
                    latlons2.append(ll)
            latlons3 = '['
            for i in range(0, len(latlons2), 2):
                latlons3 += '[%s, %s], ' % (latlons2[i], latlons2[i+1])
            latlons = str(latlons3[:-2] + ']')
        self.htmlData['INPUT_LATLONS'] = latlons
        
        self.htmlData['PROJECT'] = self.reqData.get('project', '')

        # create list of field triggers
        liTemplate = "<li><input type='checkbox' id='show_%s' name='show_%s' %s onclick=fsubmit()><label for='show_%s'> %s %s </label></li>"
        fields = self.cats[curCat]['fields']
        fieldsHtml = ''
        for field in fields:
            showField = {'name': 'on'}.get(field[0], 'off')
            showField = self.reqData.get('show_%s' % field[0], showField)
            checked = ''
            if showField == 'on':
                checked = 'checked'
            fComments = ''
            if len(field) > 3:
                fComments = ' - ' + field[3]
            li = liTemplate % (field[0], field[0], checked, field[0], field[0], fComments)
            fieldsHtml += li
        self.htmlData['LIST_OF_FIELDS'] = fieldsHtml
        
        # get data from database
        tableName = self.cats[curCat]['table']
        db = WebDatabase(tableName)
        start_date = self.reqData.get('date1', yesterday)
        stop_date = self.reqData.get('date2', today)
        season = self.reqData.get('season', 'any')
        mask = self.reqData.get('db_mask', '%')
        mask = self.cats[curCat].get('db_mask', mask)
        latlons = self.reqData.get('latlons', '')
        recs, fields, query = db.get_short_list(start_date, stop_date, season, mask, latlons)

        # create table with products or with stats
        show_stats = self.reqData.get('show_stats', 'off')
        if show_stats == 'on':
            tableHTML, jsHTML = self.make_stats(req, recs, fields)
        else:
            tableHTML, jsHTML = self.make_table(req, recs, fields)
        self.htmlData['TABLE_WITH_FILES'] = tableHTML

        # create list of files
        listHTML = self.make_list(req, recs, fields)
        self.htmlData['LIST_OF_FILES'] = listHTML
        
        # tmp
        #self.htmlData['QUERY'] = query

        # put borders of found images in the header
        borderJS = self.make_borders_js(req, recs, fields)
        self.htmlData['JS_BORDERS'] = borderJS + jsHTML
    
    def make_stats(self, req, dbRecs, dbFields):
        ''' Make table with statistics'''
        
        out = "<p class=description>Statistics:</p>\n"
        out += "<Table><tr><th>Date</th><th>Images</th></tr>\n"
        dateI = dbFields.index('sensstart')
        dates = []
        for rec in dbRecs:
            dates.append(rec[dateI].strftime('%Y-%m-%d'))
            
        uDates = list(set(dates))
        uDates.sort()
        uDatesDict = {}
        for udate in uDates:
            uDatesDict[udate] = 0
            for date in dates:
                if date == udate:
                    uDatesDict[udate] += 1
            
        for udate in uDates:
            out += "    <tr><td>%s</td><td>%d</td></tr>\n" % (udate, uDatesDict[udate])
        
        out += "</table>"
        
        jsOut = '''
        <script  type='text/javascript'>
        function add_stats_polygons(){
            for (ii = 0; ii < borders.length; ii += 1){
                add_polygon(borders[ii], '#ff0000');
            };
        };
        </script> 
        '''
        
        return out, jsOut

    def make_borders_js(self, req, dbRecs, dbFields):
        ''' Make table with statistics'''
        
        jsOut = '''
        <script  type='text/javascript'>
        var borders = [
        '''
        for rec in dbRecs:
            polyStr = rec[-1]
            polyStr = polyStr.replace('POLYGON((', '').replace(')', '').replace(',', '|').replace(' ', '|')
            polyList = polyStr.split('|')
            polyStr = '['
            for i in range(0, len(polyList), 2):
                polyStr += '[%5.3f, %5.3f], ' % (float(polyList[i]), float(polyList[i+1]))
            
            polyStr = polyStr[:-2] + ']'
            jsOut += "        %s,\n" % polyStr
        
        jsOut += '];\n</script>\n'
        
        return jsOut

    def make_table(self, req, dbRecs, dbFields):
        '''Make table with satellite images'''
        itemsPerPage = 20
        curCat = self.reqData.get('catalog', 'ANY')
        curPage = str(self.reqData.get('page', '1').strip())
        fields = self.cats[curCat]['fields']
        path = self.cats[curCat]['path']
        
        # list pages
        tableHtml = 'Images: <b>%d</b>\n ' % len(dbRecs)
        totPages = math.ceil(len(dbRecs) / float(itemsPerPage))
        tableHtml += 'Select page: '
        for tpi in range(totPages):
            pn = (tpi + 1)
            if curPage != 'all' and int(curPage) == pn:
                pageNumHtml = '&nbsp;&nbsp;&nbsp;[ # %d ] \n' % pn
            else:
                pageNumHtml = '&nbsp;&nbsp;&nbsp;<a onclick="show_page(%d)">[ # %d ]</a> \n' % (pn, pn)
            tableHtml += pageNumHtml
        if curPage == 'all':
            pageNumHtml = '&nbsp;&nbsp;&nbsp;[ # all ] \n'
        else:
            pageNumHtml = '&nbsp;&nbsp;&nbsp;<a onclick="show_page(\'all\')">[ all ]</a> \n'
        tableHtml += pageNumHtml
        tableHtml += '<br>\n'

        # open table
        thTemplate = '<TH>%s</th>'
        tableHtml += '<TABLE>\n'
        # generate table header
        rowHtml = '<TR>' + thTemplate % '#'
        for field in fields:
            showField = {'name': 'on'}.get(field[0], 'off')
            showField = self.reqData.get('show_%s' % field[0], showField)
            if showField == 'on':
                rowHtml += thTemplate % field[0]
        rowHtml += '</tr>\n'
        tableHtml += rowHtml

        # how many rows to show
        if curPage == 'all':
            rowIs = range(len(dbRecs))
        else:
            curPage = int(curPage)
            rowIs = range(itemsPerPage * (curPage - 1), itemsPerPage * curPage)

        # fill table with rows
        for i in rowIs:
            # skip out of range rows 
            if i >= len(dbRecs):
                break

            dbRec = dbRecs[i]
            # add row number
            rowHtml = '<TR><TD>%d</td>\n' % i
            # add all fields
            for field in fields:
                dbFiledI = dbFields.index(field[1])
                value = str(dbRec[dbFiledI]).strip()
                if field[0] is 'name':
                    fNname = value
                if field[0] is 'date':
                    value = value.split(' ')[0]
                    fDate = value
                showField = {'name': 'on'}.get(field[0], 'off')
                showField = self.reqData.get('show_%s' % field[0], showField)
                if showField == 'on':
                    fieldTmp = Template(field[2])
                    fieldVal = fieldTmp.safe_substitute(value=value, path=path)
                    fieldVal = fieldVal.replace('|', '')
                    rowHtml += '    <TD>' + fieldVal + '</td>\n'
            # add ToMap and MatchUp
            rowHtml += "    <td><a onclick='add_polygon(borders[%d], \"#ff0000\")'>To map</a></td>\n" % i
            rowHtml += "    <td><a onclick='search_matchup(borders[%d], \"%s\")'>Match-up</a></td></tr>\n" % (i, fDate)
            rowHtml += '</tr>\n'
            tableHtml += rowHtml
        # close table
        tableHtml += '</table>'
        
        return tableHtml, "<script  type='text/javascript'>function add_stats_polygons(){}</script>"

    def make_list(self, req, dbRecs, dbFields):
        '''Make list of files with full path'''
        listHTML = ''
        pathI = dbFields.index('path')
        nameI = dbFields.index('name')
        for dbRec in dbRecs:
            listHTML += '%s/%s<br>\n' % (dbRec[pathI].strip(), dbRec[nameI].strip())
        return listHTML
            
        
    def render(self):
        '''Substitute special tags with values'''
        return self.htmlTmp.safe_substitute(self.htmlData) 

def handler(req):
    req.content_type = 'html'

    p = Page(req, 'sadcat.html')
    p.set_params(req)
    req.write(p.render())
    # temp:
    #request_data = util.FieldStorage(req, keep_blank_values=True)
    #req.write(str(request_data.items()))
    
    return apache.OK
