# -*- coding: utf-8 -*-

# Create your views here.


from multiprocessing import Process

from django.contrib.auth import *
from django.contrib.auth.decorators import *

from django.core import serializers
from django.http import *
from django.shortcuts import *
from django.views.decorators.csrf import *
from django.utils import *

from django.views.generic import CreateView, DeleteView
from django.db.models import Q

from categories.models import *
from dateutil.relativedelta import *
from excel_response import ExcelResponse

from haystack.inputs import AutoQuery
from haystack.query import SearchQuerySet

from ntuh import settings
from registry.models import *
from .utils import RenewSchedule

#from multiuploader.models import *

import calendar, datetime, json, os
import io as StringIO

import ck.models


try:
    from collections import OrderedDict
except:
    from ordereddict import OrderedDict

ROOT = lambda base : os.path.join(os.path.dirname(__file__), base).replace('\\','/')

@login_required
def op_category(request):
#    source_array = [{'value': 0, 'text': "None"}]
    source_array = [(0, "None")]

    array = OrderedDict()
    
    array[0] = 'None'
    
#    L = list(Category.objects.get(name='手術').get_children())
#    L.sort(key=lambda c: (c.order, c.id))
    L = [Category.objects.get(name='手術')]
    for d in L[0].get_descendants():
        array[d.id] = str(d).replace('手術 > ', '')
#        source_array.append({'value': d.id, 'text': str(d).replace('手術 > ', '')})
        source_array.append((d.id, str(d).replace('手術 > ', '')))


    return HttpResponse(json.dumps(source_array), content_type='application/json')

    return HttpResponse(json.dumps(array), content_type='application/json')


    while L:
        c = L[0]
        del L[0]
        if c.is_leaf_node():
            array[c.id] = str(c).replace('手術 > ', '')
        else:
            if c.name.lower().find('others') != -1:
                array[c.id] = str(c).replace('手術 > ', '')
#            L[:0] = c.get_children()
            children = list(c.get_children())
            L[:0] = sorted(children, key=lambda c: (c.order, c.id))

#    L = list(Category.objects.get(name='手術').get_children())
#    L.sort(key=lambda c: (c.order, c.id))
#    while L:
#        c = L[0]
#        del L[0]
#        array.append(c)
#        if c.is_leaf_node():
#            pass
#        else:
#            children = list(c.get_children())
#            L[:0] = sorted(children, key=lambda c: (c.order, c.id))

    
#    for c in Category.objects.filter(tree_id=1):
#        if c.is_leaf_node():
#            array[c.id] = str(c)
        
    return HttpResponse(json.dumps(array), content_type='application/json')



#@csrf_exempt
def op_edit(request):
    field, id = request.POST.get('id', '').split('_')
#    print field, id
    value = request.POST.get('value', '').strip()
    if value in ('', 'None', '0'):
        value = None
    op = OPSchedule.objects.get(id=id)
    
    if field == 'category':
        op.category_id = value
        if value:
            op.save()
            return HttpResponse(Category.objects.get(id=value))
    elif field == 'Memo':
        op.Memo = value
    elif field == 'Morbidity':
        op.Morbidity = value
    elif field == 'Mortality':
        op.Mortality = value
    elif field == 'PatDignosis':
        op.PatDignosis = value
        
    op.save()
    return HttpResponse(value)

@login_required
def op_note(request, PatChartNo, date):
    
    display = request.GET.get('display', False) # display 時間資訊 & 醫令資訊
    pdf = request.GET.get('pdf', False)
    
    for op in OPNote.objects.filter(PatChartNo = PatChartNo, date = date):
        pattern = '\\"Yellow\\">(?P<first>.)(?P<name>.*?)\\((?P<sex>.*?),(?P<dob>.*?),(?P<age>.*?)\\)</TD>'
        repl    = '"Yellow">\g<first>**(\g<sex>,****/**/**,\g<age>,%s)</TD>' % PatChartNo
        
        if pdf:
            import xhtml2pdf.pisa as pisa
            
            from reportlab.pdfbase import pdfmetrics
            from reportlab.pdfbase.ttfonts import TTFont
            pdfmetrics.registerFont(TTFont('ArialUni', ROOT('../static/ArialUni.ttf')))  
            from xhtml2pdf import default
            default.DEFAULT_FONT["helvetica"]="ArialUni"
    
            content = op.content.replace('style="display: none"', '')
            html = re.sub(pattern, repl, content)
            
            result = StringIO.StringIO()
#            pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-1")), result)
#            pisa.showLogging(debug=True)
#            pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("UTF-8")), result, encoding='UTF-8', raise_exception = False)
#            pdf = pisa.CreatePDF(StringIO.StringIO(html.encode("UTF-8")), result, encoding='UTF-8')
#            pdf = pisa.CreatePDF(StringIO.StringIO(html.encode("UTF-8")), result, encoding='UTF-8', raise_exception = True)
            pdf = pisa.CreatePDF(StringIO.StringIO(html.encode("UTF-8")), result, encoding='UTF-8', raise_exception = False)
            return HttpResponse(result.getvalue(), content_type='application/pdf')
#            if not pdf.err:
#                return HttpResponse(result.getvalue(), mimetype='application/pdf')
#            return HttpResponse('We had some errors<pre>%s</pre>' % cgi.escape(html))

        elif display:
            return HttpResponse(op.content.replace('style="display: none"', ''))
        else:
            return HttpResponse(op.content)
        
    return HttpResponse()

@login_required
def patho_report(request, PatChartNo, date):
    for patho in PathologyReport.objects.filter(ChartNo = PatChartNo).order_by('-SpecimenGetDate'):
        matches = re.findall('(<table id="rReportTab.*?</table>)', patho.html, re.DOTALL) 
        return HttpResponse(matches[0])
    
    return HttpResponse()


#@login_required
#def op_images(request, PatChartNo, date):
#    
#    items = MultiuploaderImage.objects.all()
#    return render_to_response('registry/op_images.html', 
##                              {'oplist': oplist},
#                                {'items':items},
#                              context_instance=RequestContext(request))


@login_required
@csrf_exempt
def op_prepare(request):
    date1 = request.GET.get('date1', '0')
    print1 = request.GET.get('print1', False)
    renew1 = request.GET.get('renew1', False)
    rooms1 = request.GET.get('rooms1', False)
    delete1 = request.GET.get('delete1', False)
    
    if delete1:
        # print delete1
        obj = OPSchedule.objects.get(id=delete1)
        obj.delete()
    
    if renew1:
        p = Process(target=RenewSchedule)
        p.start()
        p.join()
    
    if date1 != '0':
        oplist = OPSchedule.objects.filter(OPDate=date1).order_by('OPDate', 'OpRoomNo', 'OpSeqNo')
        date2 = datetime.datetime.strptime(date1,'%Y-%m-%d').strftime('%Y-%m-%d(W%w,%a)')
        # print date2
    else:
        date1 = 'Upcoming'
        date2 = 'Upcoming'
        oplist = OPSchedule.objects.filter(OPDate__gte=datetime.date.today()).order_by('OPDate', 'OpRoomNo', 'OpSeqNo')
        
        
    dates = oplist.values_list('OPDate', flat=True)
    dates=set(dates)
    dates=list(dates)
    dates=sorted(dates)

    rooms = oplist.values_list('OpRoomNo', flat=True)
    rooms=set(rooms)
    rooms=rooms-set([None])
    rooms=list(rooms)
    rooms=sorted(rooms)
    
#     print rooms
    
    if print1:
        # print type(rooms1), rooms1
        # return render_to_response('registry/op_prepare_print.html', 
        #                       {
        #                        'oplist': oplist,
        #                        'content_type': ContentType.objects.get(app_label="registry", model="OPSchedule").model,
        #                        'dates': dates,
        #                        'rooms': json.loads(rooms1),
        #                        'NOADS': settings.NOADS,
        #                        'date1': date1,
        #                        'date2': date2,
        #                        },
        #                       context_instance=RequestContext(request))
        return render(request, 'registry/op_prepare_print.html', {
            'oplist': oplist,
            'content_type': ContentType.objects.get(app_label="registry", model="OPSchedule").model,
            'dates': dates,
            'rooms': json.loads(rooms1),
            'NOADS': settings.NOADS,
            'date1': date1,
            'date2': date2,
        })
    else:
        HTTP_USER_AGENT = request.META['HTTP_USER_AGENT']
        if 'Chrome' in HTTP_USER_AGENT:
            HTTP_USER_AGENT = 'Good! You are using %s' % HTTP_USER_AGENT.replace('Chrome', '<span class="label label-success">Chrome</span>')
        else:
            HTTP_USER_AGENT = '<span class="label label-warning">Chrome</span> is suggested, but you are using %s' % HTTP_USER_AGENT
        # return render_to_response('registry/op_prepare.html', 
        #                       {
        #                        'oplist': oplist,
        #                        'content_type': ContentType.objects.get(app_label="registry", model="OPSchedule").model,
        #                        'dates': dates,
        #                        'rooms': rooms,
        #                        'rooms_json': json.dumps(rooms),
        #                        'NOADS': settings.NOADS,
        #                        'HTTP_USER_AGENT': HTTP_USER_AGENT,
        #                        },
        #                       context_instance=RequestContext(request))
        return render(request, 'registry/op_prepare.html', {
            'oplist': oplist,
            'content_type': ContentType.objects.get(app_label="registry", model="OPSchedule").model,
            'dates': dates,
            'rooms': rooms,
            'rooms_json': json.dumps(rooms),
            'NOADS': settings.NOADS,
            'HTTP_USER_AGENT': HTTP_USER_AGENT,
        })


@login_required
def op_schedule(request):
    month = request.POST.get('month', False)
    
    if month:
        mm, yy = month.split('/')
        m = int(mm)
        y = int(yy)
        weakday, number = calendar.monthrange(y, m)
        start_date = datetime.date(y, m, 1)
        end_date = datetime.date(y, m, number)
        oplist = OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).order_by('OPDate', 'OpRoomNo', 'OpSeqNo')    
    else:
        oplist = OPSchedule.objects.filter(Complete='完成').order_by('-OPDate', 'OpRoomNo', 'OpSeqNo')[0:200]
        
#    content_type = ContentType.objects.get(app_label="registry", model="OPSchedule").model
        
    # return render_to_response('registry/op_schedule.html', 
    #                           {
    #                            'oplist': oplist,
    #                            'content_type': ContentType.objects.get(app_label="registry", model="OPSchedule").model, 
    #                            'NOADS': settings.NOADS,
    #                            },
    #                           context_instance=RequestContext(request))
    return render(request, 'registry/op_schedule.html', {
        'oplist': oplist,
        'content_type': ContentType.objects.get(app_label="registry", model="OPSchedule").model, 
        'NOADS': settings.NOADS,
    })


@login_required
def op_uncategorized(request):
    month = request.POST.get('month', False)
    
    if month:
        mm, yy = month.split('/')
        m = int(mm)
        y = int(yy)
        weakday, number = calendar.monthrange(y, m)
        start_date = datetime.date(y, m, 1)
        end_date = datetime.date(y, m, number)
        oplist = OPSchedule.objects.filter(OPDate__range=(start_date, end_date)).filter(category=None).filter(Complete='完成').order_by('OPDate', 'OpRoomNo', 'OpSeqNo')    
    else:
        end_date = datetime.datetime.now() - datetime.timedelta(days=3*365)
        # print end_date
        oplist = OPSchedule.objects.filter(OPDate__gt= end_date).filter(category=None).filter(Complete='完成').order_by('-OPDate', 'OpRoomNo', 'OpSeqNo')[0:100]
        
    # return render_to_response('registry/op_schedule.html',
    #                           {
    #                            'oplist': oplist,
    #                            'content_type': ContentType.objects.get(app_label="registry", model="OPSchedule").model, 
    #                            },
    #                           context_instance=RequestContext(request))
    return render(request, 'registry/op_schedule.html', {
        'oplist': oplist,
        'content_type': ContentType.objects.get(app_label="registry", model="OPSchedule").model, 
    })


def SRSCount(icd9s, year, month = False):
    count = 0
    for icd in icd9s:
        query = ck.models.Treatment.objects.using('ck').filter(icd9__code__istartswith=icd)
        if month:
            count += query.filter(date_completed__year=year).filter(date_completed__month=month).count()
        else:
            count += query.filter(date_completed__year=year).count()
    return count
    
def SRSCountAll(year, month = False):    
    count = 0
    L = list(Category.objects.get(name='手術').get_children())
    L.sort(key=lambda c: (c.order, c.id))
    while L:
        c = L[0]
        del L[0]
        if c.is_leaf_node():
            pass
        else:
            children = list(c.get_children())
            L[:0] = sorted(children, key=lambda c: (c.order, c.id))
        
        try:    # SRS
            desc = json.loads(c.description)
        except:
            desc = {}
        if 'icd9' in desc:
            count += SRSCount(desc['icd9'], year, month)
         
    return count

def SRSC():
    if settings.SPECIALTY == '新竹分院' or True:
        return 0
    else:
        return SRSCountAll(year, month)


def CategoryMonthCount(year, month, cat): # including subcat and SRS
    if month:
        weakday, number = calendar.monthrange(year, month)
        start_date = datetime.date(year, month, 1)
        end_date = datetime.date(year, month, number)
    else:
        start_date = datetime.date(year, 1, 1)
        end_date = datetime.date(year, 12, 31)

#    if settings.SPECIALTY == '新竹分院' or True:
#        SRSC = 0
#    else:
#        SRSC = SRSCountAll(year, month)

    if cat in [u'手術總數', None]:
        return OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).count() + SRSC()
    
    if cat in [u'手術病人數']:
        return OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).values('PatChartNo').distinct().count() + SRSC()
    
    count = 0
    L = [cat]
    while L:
        c = L[0]
        del L[0]
        if c.is_leaf_node():
            pass
        else:
            children = list(c.get_children())
            L[:0] = sorted(children, key=lambda c: (c.order, c.id))

        try:    # SRS
            desc = json.loads(c.description)
        except:
            desc = {}

        if 'icd9' in desc:
            if settings.SPECIALTY != '新竹分院':
                count += SRSCount(desc['icd9'], year, month)
        else:
            count += OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).filter(category=c).count()
            
    return count


def CategoryMonthCountMM(year, month, cat): # return count, include morbidity & mortality, not including subcat
    if month:
        weakday, number = calendar.monthrange(year, month)
        start_date = datetime.date(year, month, 1)
        end_date = datetime.date(year, month, number)
    else:
        start_date = datetime.date(year, 1, 1)
        end_date = datetime.date(year, 12, 31)
        
    memos = []
    morbs = []
    morts = []
    
    if cat == u'手術總數':
        case      = OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).count()
        emergency = OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).exclude(OpTypeName=u'預').count()
        morbidity = OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).filter(Morbidity__isnull=False).count()
        mortality = OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).filter(Mortality__isnull=False).count()
    else:
        cases = OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).filter(category=cat)
        case      = cases.count()
        emergency = cases.exclude(OpTypeName=u'預').count()
        morbidity = cases.filter(Morbidity__isnull=False).count()
        mortality = cases.filter(Mortality__isnull=False).count()
        
        for c in cases:
            if c.Memo:
                memos.append("%s %s" % (c.PatChartNo, c.Memo.replace(str(c.PatChartNo), ''))) 
            if c.Morbidity:
                morbs.append("%s %s" % (c.PatChartNo, c.Morbidity.replace(str(c.PatChartNo), ''))) 
            if c.Mortality:
                morts.append("%s %s" % (c.PatChartNo, c.Mortality.replace(str(c.PatChartNo), ''))) 
    
    return {
            'case': case,
            'emergency': emergency,
            'morbidity': morbidity,
            'mortality': mortality,
            
            'memos': '\n'.join(memos), 
            'morbs': '\n'.join(morbs),
            'morts': '\n'.join(morts),
            }

def CategoryMonthMM(year, month, cat): # return records
    if month:
        weakday, number = calendar.monthrange(year, month)
        start_date = datetime.date(year, month, 1)
        end_date = datetime.date(year, month, number)
    else:
        start_date = datetime.date(year, 1, 1)
        end_date = datetime.date(year, 12, 31)
        
    return OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).filter(category=cat)


def xls_to_response(xls, fname):
    response = HttpResponse(content_type="application/ms-excel")
    response['Content-Disposition'] = 'attachment; filename=%s' % fname
    xls.save(response)
    return response

#return xls_to_response(xls,'foo.xls')


def data_to_xls(data, fname, blank_zero = True ):
    from tempfile import TemporaryFile
    import xlwt
    
#    algn1 = xlwt.Alignment() 
#    algn1.wrap = 1 
#    style1 = xlwt.XFStyle() 
#    style1.alignment = algn1 
    style1 = xlwt.easyxf("alignment: wrap on") 
   
    book = xlwt.Workbook()
    sheet1 = book.add_sheet('Sheet 1')
    row = 0
    for r in data:
        col = 0
        for c in r:
            if blank_zero and c == 0:
        	    col += 1
        	    continue
            # print (type(c))
#             if unicode(c).find('\n') != -1:    #UnicodeDecodeError
            # if type(c) in [str, unicode] and '\n' in c:
            if type(c) is str and '\n' in c:
                sheet1.write(row, col, c, style1)
            else:
                sheet1.write(row, col, c)
            col += 1
        row += 1
    return xls_to_response(book, fname)

@login_required
def op_month_old(request):
    last_month = datetime.date.today() + relativedelta( months = -1 )

    month = last_month.strftime('%m/%Y')
    month = request.GET.get('month', month)
    month = request.POST.get('month', month)
    
    mm, yy = month.split('/')
        
    
    L0 = list(Category.objects.get(name='手術').get_children())
    L0.sort(key=lambda c: (c.order, c.id))
    LOP  = []
    LSRS = []
    for l in L0:    #OP then SRS
        if l.name.find('SRS') != -1:
            LSRS.append(l)
        else:
            LOP.append(l)
            
    L0 = LOP + LSRS

    data = []
    
    T = CategoryMonthCountMM(int(yy), int(mm), u'手術總數')
    data.append([u'項目', u'手術', u'急', '', 'Morbidity', '', 'Mortality', ''])
    data.append([u'手術總數', T['case'], T['emergency'], '', T['morbidity'], '', T['mortality'], ''])
    data.append([''])
    
    for L1 in L0:
        L = [L1]
        array = []
        while L:
            c = L[0]
            del L[0]
            array.append(c)
            if c.is_leaf_node():
                pass
            else:
                children = list(c.get_children())
                L[:0] = sorted(children, key=lambda c: (c.order, c.id))
    
            caseS = 0
            emergencyS = 0
            morbidityS = 0
            mortalityS = 0
        data.append([u'項目', u'手術', u'急', '', 'Morbidity', '', 'Mortality', ''])
            
        for cat in array:
            try:
                row = ['  ' * cat.level + cat.name]
            except:
                row = [cat]
                
            try:    # SRS
                desc = json.loads(cat.description)
            except:
                desc = {}
            if 'icd9' in desc:
                C = {
                     'case': SRSCount(desc['icd9'], int(yy), int(mm)),
                     'emergency': 0,
                     'morbidity': 0,
                     'mortality': 0,
                     'memos': '',
                     'morbs': '',
                     'morts': '',
                     }
            else: # surgery
                C = CategoryMonthCountMM(int(yy), int(mm), cat)
                
            caseS += C['case']
            emergencyS += C['emergency']
            morbidityS += C['morbidity']
            mortalityS += C['mortality']
            
            row.extend([C['case'], C['emergency'], C['memos'], C['morbidity'], C['morbs'], C['mortality'], C['morts']])
    
            data.append(row)
        if len(array)>1:
            data.append(['  Subtotal', caseS, emergencyS, '', morbidityS, '', mortalityS, ''])
        data.append([''])
    

#    data.append([u'項目', u'手術', u'急', 'Morbidity', 'Mortality'])
    data.append([u'未分類', CategoryMonthCountMM(int(yy), int(mm), None)['case']])
    data.append([u'手術總數', T['case'], T['emergency'], '', T['morbidity'], '', T['mortality'], ''])
    data.append([u'含CyberKnife', T['case'] + SRSCountAll(int(yy), int(mm))])


    if request.GET.get('xls', False):
        return data_to_xls(data, '%s.xls' % month)
    else:
        # return render_to_response('registry/op_month.html', 
        #                           {
        #                            'data': data,
        #                            'month': month,
        #                            },
        #                           context_instance=RequestContext(request))
        return render(request, 'registry/op_month.html', {
            'data': data,
            'month': month,
        })

@login_required
def op_month(request):
    last_month = datetime.date.today() + relativedelta( months = -1 )

    month = last_month.strftime('%m/%Y')
    month = request.GET.get('month', month)
    month = request.POST.get('month', month)
    
    mm, yy = month.split('/')
        
    
    L0 = list(Category.objects.get(name='手術').get_children())
    L0.sort(key=lambda c: (c.order, c.id))
    LOP  = []
    LSRS = []
    for l in L0:    #OP then SRS
        if l.name.find('SRS') != -1:
            LSRS.append(l)
        else:
            LOP.append(l)
            
    L0 = LOP + LSRS

    data = []
    
    T = CategoryMonthCountMM(int(yy), int(mm), u'手術總數')
    data.append([u'項目', u'手術', u'急', '', 'Morbidity', '', 'Mortality', ''])
    data.append([u'手術總數', T['case'], T['emergency'], '', T['morbidity'], '', T['mortality'], ''])
    data.append([''])
    
    cats = []            
        
    for L1 in L0:
        L = [L1]
        array = []
        while L:
            c = L[0]
            del L[0]
            array.append(c)
            if c.is_leaf_node():
                pass
            else:
                children = list(c.get_children())
                L[:0] = sorted(children, key=lambda c: (c.order, c.id))
    
            caseSum = 0
            emergencySum = 0
            morbiditySum = 0
            mortalitySum = 0
        data.append([u'項目', u'手術', u'急', '', 'Morbidity', '', 'Mortality', ''])
        
        for cat in array:
            try:
                rowtitle = '  ' * cat.level + cat.name
            except:
                rowtitle = cat
                
            try:    # SRS
                desc = json.loads(cat.description)
            except:
                desc = {}
                
            MemoS = []
            MorbidityS = []
            MortalityS = []
                
            if 'icd9' in desc:
                records = None

                if settings.SPECIALTY == '新竹分院':
                    count = 0
                else:
                    count = SRSCount(desc['icd9'], int(yy), int(mm))

                emergency = 0
                morbidity = 0
                mortality = 0
            else: # surgery
                records = CategoryMonthMM(int(yy), int(mm), cat)
                count = records.count()
                emergency = records.exclude(OpTypeName=u'預').count()
                morbidity = records.exclude(Morbidity__isnull=True).count()
                mortality = records.exclude(Mortality__isnull=True).count()
                
                for r in records:
                    chartno = str(r.PatChartNo)
                    if r.Memo:
                        if chartno in r.Memo:
                            r.Memo= r.Memo.replace(chartno, '').strip()
                            r.save()
                        MemoS.append(r.Memo)
                    if r.Morbidity:
                        if chartno in r.Morbidity:
                            r.Morbidity= r.Morbidity.replace(chartno, '').strip()
                            r.save()
                        MorbidityS.append(r.Morbidity)
                    if r.Mortality:
                        if chartno in r.Mortality:
                            r.Mortality= r.Mortality.replace(chartno, '').strip()
                            r.save()
                        MortalityS.append(r.Mortality)
                        
            cats.append({
                         'title': rowtitle,
                         'desc': desc,
                         'records': records,
                         'count': count if count else '',
                         'emergency': emergency if emergency else '',
                         'morbidity': morbidity if morbidity else '',
                         'mortality': mortality if mortality else '',
                         })
                
            data.append([rowtitle, count, emergency, 
                         '\n'.join(MemoS), 
                         morbidity, 
                         '\n'.join(MorbidityS), 
                         mortality, 
                         '\n'.join(MortalityS), 
                         ])
            
            caseSum += count
            emergencySum += emergency
            morbiditySum += morbidity
            mortalitySum += mortality
            
            
        if len(array)>1:
            data.append(['  Subtotal', caseSum, emergencySum, '', morbiditySum, '', mortalitySum, ''])
        data.append([''])
        
    uncategorized = CategoryMonthCountMM(int(yy), int(mm), None)['case']

    if uncategorized:
        cats.append({
                     'title': '未分類',
                     'count': CategoryMonthCountMM(int(yy), int(mm), None)['case'],
                     })
    cats.append({
                 'title': '手術總數',
                 'count': T['case'],
                 'emergency': T['emergency'],
                 'morbidity': T['morbidity'],
                 'mortality': T['mortality'],
                 })
    if settings.SPECIALTY != '新竹分院':
        cats.append({
                    'title': '含CyberKnife',
                    'count': T['case'] + SRSCountAll(int(yy), int(mm)),
                    })
            
#     print json.dumps(cats)
    data.append([u'未分類', uncategorized])
    data.append([u'手術總數', T['case'], T['emergency'], '', T['morbidity'], '', T['mortality'], ''])
    if settings.SPECIALTY != '新竹分院':
        data.append([u'含CyberKnife', T['case'] + SRSCountAll(int(yy), int(mm))])
    
    
    

    if request.GET.get('xls', False):
        return data_to_xls(data, '%s.xls' % month)
    else:
        # return render_to_response('registry/op_month.html', 
        #                           {
        #                            'cats': cats,
        #                            'data': data,
        #                            'month': month,
        #                            },
        #                           context_instance=RequestContext(request))
        return render(request,'registry/op_month.html', 
            {
            'cats': cats,
            'data': data,
            'month': month,
            })

    
@login_required
def op_year(request):
    year = int(request.POST.get('year', datetime.date.today().year))
    year = int(request.GET.get('year', year))
    
    array = []
    
    L = list(Category.objects.get(name='手術').get_children())
    L.sort(key=lambda c: (c.order, c.id))
    while L:
        c = L[0]
        del L[0]
        array.append(c)
        if c.is_leaf_node():
            pass
        else:
            children = list(c.get_children())
            L[:0] = sorted(children, key=lambda c: (c.order, c.id))
    
    data = []
#    data.append([u'項目', u'一月', u'二月', u'三月', u'四月', u'五月', u'六月', u'七月', u'八月', u'九月', u'十月', u'十一', u'十二', u'年度總計']);
    
#    array.extend([u'手術總數', None])
    
#    SRS = {}
#    for month in range(1, 13):
#        SRS[month] = 0
        
    for cat in array:
        try:
            row = ['  ' * cat.level + cat.name]
        except:
            row = [cat]
#        try:    # SRS
#            desc = json.loads(cat.description)
#        except:
#            desc = {}
        for month in range(1, 13):
#            if desc.has_key('icd9'):
#                srs = SRSCount(desc['icd9'], year, month)
#                row.append(srs)
#                SRS[month] += srs
#            else: # surgery
                row.append(CategoryMonthCount(year, month, cat))
                
#        if desc.has_key('icd9'):
#            row.append(SRSCount(desc['icd9'], year, False))
#        else:
        row.append(CategoryMonthCount(year, False, cat))
            
        data.append(row)
            
#        手術總數

    row = [u'手術總數']
    Ytotal = 0
    for month in range(1, 13):
        Mtotal = CategoryMonthCount(year, month, None) 
        row.append(Mtotal)
        Ytotal += Mtotal
    row.append(Ytotal)
    data.append(row)
    
    row = [u'手術病人數']
    Ytotal = 0
    for month in range(1, 13):
        Mtotal = CategoryMonthCount(year, month, u'手術病人數') 
        row.append(Mtotal)
        Ytotal += Mtotal
    row.append(Ytotal)
    data.append(row)
    
    
    
#    print data

    if request.GET.get('xls', False):
        data.insert(0, [u'項目', u'一月', u'二月', u'三月', u'四月', u'五月', u'六月', u'七月', u'八月', u'九月', u'十月', u'十一', u'十二', u'年度總計']);
        return data_to_xls(data, '%d.xls' % year)
    else:
        # return render_to_response('registry/op_year.html', 
        #                           {
        #                            'data': data,
        #                            'year': year,
        #                            },
        #                           context_instance=RequestContext(request))
        return render(request, 'registry/op_year.html', 
                                  {
                                   'data': data,
                                   'year': year,
                                   })


#102 年度 1 月至 12 月脊椎、腦血管、腦瘤手術記錄報表(序號、日期、病歷號碼、年齡、Diagnosis 、Operation) 造冊。
@login_required
def op_report(request):
    year = int(request.POST.get('year', datetime.date.today().year))
    year = int(request.GET.get('year', year))
    
    
    start_date = datetime.date(year, 1, 1)
    end_date = datetime.date(year, 12, 31)

    query = OPSchedule.objects.filter(Complete='完成').filter(OPDate__range = (start_date, end_date))
    
    data = []
    for obj in query:
        
        try:
            ancestors = obj.category.get_ancestors()
            anc = unicode(ancestors[1])
        except:
            ancestors = []
            anc = unicode(obj.category)
        
        row = [obj.id, obj.OPDate.strftime('%Y-%m-%d'), obj.PatChartNo, obj.PatAge, obj.PatDignosis, obj.MainOpModeTitle, obj.MainOpMode, unicode(obj.category), anc]
        data.append(row)

#        print dir(obj.category)
#        print obj.category
#        print obj.category.get_ancestors()

    return data_to_xls(data, '%d.xls' % year)
    
# using haystack
@login_required
def op_search(request):
    q = request.GET.get('q', '')
    q = request.POST.get('q', q)
    
    
    search_submit   = request.POST.get('search_submit',   None)
    search_xls      = request.POST.get('search_xls',      None)
    search_category = request.POST.get('search_category', None)
    
    data = [] 

    if q and len(q) >= 2:

        results = SearchQuerySet().filter(content=AutoQuery(q)).load_all()
        PK = results.values_list('pk', flat=True)
        PK = set(PK)
        objs = OPNote.objects.filter(pk__in=PK).order_by('-date','PatChartNo')

        if search_xls:
            # objs = OPNote.objects.filter(content__icontains=q).order_by('-date','PatChartNo')
            obj2 = objs.extra(
                              select = {
                                        'PatName': 'registry_opschedule.PatName',
                                        'PatSex': 'registry_opschedule.PatSex',
                                        'PatAge': 'registry_opschedule.PatAge',
                                        'PatDignosis': 'registry_opschedule.PatDignosis',
                                        'MainOpMode': 'registry_opschedule.MainOpMode',
                                        'MainOpModeTitle': 'registry_opschedule.MainOpModeTitle',
                                        'OpDoctorName': 'registry_opschedule.OpDoctorName',
                                        },
                              tables = ['registry_opschedule'],
                              where = [
                                       'registry_opschedule.PatChartNo=registry_opnote.PatChartNo',
                                       'registry_opschedule.OPDate=registry_opnote.date',
                                       ]
                             )[:2000]
            return ExcelResponse(obj2, 
                # auto_adjust_width=False
                )
        # elif search_category:

        #     pass

        else:
            ids = []
            for note in objs[:2000]:
                enddate = note.date
                startdate = enddate + datetime.timedelta(days=-1)
                schedule = OPSchedule.objects.filter(Complete='完成').filter(PatChartNo=note.PatChartNo, OPDate__range=[startdate, enddate]).order_by('-OPDate', '-StartTime')
                if schedule:
                    for s in schedule:
                        if s.id not in ids:
                            ids.append(s.id)
                            data.append([note, s])
                            break
                else:
                    data.append([note, None])
            if search_category:
                            
                objs = OPSchedule.objects.filter(pk__in=list(ids))
                    
                array = []
                
                L = list(Category.objects.get(name='手術').get_children())
                L.sort(key=lambda c: (c.order, c.id))
                while L:
                    c = L[0]
                    del L[0]
                    array.append(c)
                    if c.is_leaf_node():
                        pass
                    else:
                        children = list(c.get_children())
                        L[:0] = sorted(children, key=lambda c: (c.order, c.id))
                        
            #     print array
                
                data = []
                    
                for cat in array:
                    try:
                        row = ['  ' * cat.level + cat.name]
                    except:
                        row = [cat]
                    row.append(objs.filter(category=cat).count())
                        
                    data.append(row)
                        
                return data_to_xls(data, 'search.xls')



    return render(request, 'registry/op_search.html', 
                                  {
                                   'data': data,
                                   'q': q,
                                   })


# using mysql icontain
@login_required
def op_search2(request):
    q = request.GET.get('q', '')
    q = request.POST.get('q', q)
    
    
    search_submit   = request.POST.get('search_submit',   None)
    search_xls      = request.POST.get('search_xls',      None)
    search_category = request.POST.get('search_category', None)
    
    data = [] 

    if q and len(q) >= 2:
        objs = OPNote.objects.filter(content__icontains=q).order_by('-date','PatChartNo')
        if search_xls:
            obj2 = objs.extra(
                              select = {
                                        'PatName': 'registry_opschedule.PatName',
                                        'PatSex': 'registry_opschedule.PatSex',
                                        'PatAge': 'registry_opschedule.PatAge',
                                        'PatDignosis': 'registry_opschedule.PatDignosis',
                                        'MainOpMode': 'registry_opschedule.MainOpMode',
                                        'MainOpModeTitle': 'registry_opschedule.MainOpModeTitle',
                                        'OpDoctorName': 'registry_opschedule.OpDoctorName',
                                        },
                              tables = ['registry_opschedule'],
                              where = [
                                       'registry_opschedule.PatChartNo=registry_opnote.PatChartNo',
                                       'registry_opschedule.OPDate=registry_opnote.date',
                                       ]
                             )[:2000]
            return ExcelResponse(obj2, 
                # auto_adjust_width=False
                )
        else:
            ids = []
            for note in objs[:2000]:
                enddate = note.date
                startdate = enddate + datetime.timedelta(days=-1)
                schedule = OPSchedule.objects.filter(Complete='完成').filter(PatChartNo=note.PatChartNo, OPDate__range=[startdate, enddate]).order_by('-OPDate', '-StartTime')
                if schedule:
                    for s in schedule:
                        if s.id not in ids:
                            ids.append(s.id)
                            data.append([note, s])
                            break
                else:
                    data.append([note, None])
            if search_category:
                            
                objs = OPSchedule.objects.filter(pk__in=list(ids))
                    
                array = []
                
                L = list(Category.objects.get(name='手術').get_children())
                L.sort(key=lambda c: (c.order, c.id))
                while L:
                    c = L[0]
                    del L[0]
                    array.append(c)
                    if c.is_leaf_node():
                        pass
                    else:
                        children = list(c.get_children())
                        L[:0] = sorted(children, key=lambda c: (c.order, c.id))
                        
            #     print array
                
                data = []
                    
                for cat in array:
                    try:
                        row = ['  ' * cat.level + cat.name]
                    except:
                        row = [cat]
                    row.append(objs.filter(category=cat).count())
                        
                    data.append(row)
                        
                return data_to_xls(data, 'search.xls')
        
    # return render_to_response('registry/op_search.html', 
    #                               {
    #                                'data': data,
    #                                'q': q,
    #                                },
    #                               context_instance=RequestContext(request))
    return render(request, 'registry/op_search.html', 
                                  {
                                   'data': data,
                                   'q': q,
                                   })


def handling_charge(start, end): # calculate and fix start end time 
    if start.hour  < 6:
        return (start, end, 2000)
    if start.date() != end.date():
        return (start, end, 2000)
    if start.hour  < 8:
        return (start, end, 1500)
    if start.hour  >= 17:
        return (start, end, 1500)
    
    try:
        holiday = Holiday.objects.get(date=start.date())
    except:
        holiday = False
        
    if holiday:
        if holiday.worktill:
            if start.time() >= holiday.worktill:
                return (start, end, 1500)
            return (start, end, 0)
        return (start, end, 1500)
        
    if start.isoweekday() == 7: #Sunday
        return (start, end, 1500)
        
    if start.isoweekday() == 6: #Saturday
        if start.hour  >= 12:
            return (start, end, 1500)
        if end.hour  >= 12:
            start = datetime.datetime.combine(start.date(), datetime.time(12,00))
        if end.hour == 12:
            end = datetime.datetime.combine(start.date(), datetime.time(13,00))
        return (start, end, 1500) # fix start time for W6
    
    return (start, end, 0)

@login_required
def op_charge(request):
    last_month = datetime.date.today() + relativedelta( months = -1 )
#     month = request.REQUEST.get('month', last_month.strftime('%m/%Y'))
    month = request.POST.get('month', last_month.strftime('%m/%Y'))
#    q = request.POST.get('q', False)

    mm, yy = month.split('/')
    m = int(mm)
    y = int(yy)
    weakday, number = calendar.monthrange(y, m)
    start_date = datetime.date(y, m, 1)
    end_date = datetime.date(y, m, number)
    
    oplist = OPSchedule.objects.filter(Complete='完成').filter(OPDate__range=(start_date, end_date)).order_by('OpDoctorName', 'id')    
#    if q and len(q) > 2:
#        oplist = oplist.filter(content__contains=q)

    data = []
    
    xls = request.GET.get('xls', False)
    
    for op in oplist:

        if op.OpTypeName == u'預':
            continue

        StartTime = datetime.datetime.combine(op.OPDate, op.StartTime)
        EndTime = StartTime + datetime.timedelta(minutes=op.SpendTime)
        
        start, end, charge = handling_charge(StartTime, EndTime)
        
        hours = round((end - start).seconds / 360 /10.0, 1)
        if hours < 1:
            hours = 1.0
        
        if charge:
            data.append([
                     '',
                     op.OpDoctorName,
                     u'緊急手術',
#                      op.OPDate.strftime('%m-%d(%a)') if xls else op.OPDate.strftime('%Y-%m-%d'),
#                     op.OPDate.strftime('%m-%d(%a)').decode('utf-8'),
                     op.OPDate.strftime('%m-%d(%a)'),
                     '%s-%s' % (start.strftime('%H:%M'), end.strftime('%H:%M')),
                     hours,
                     op.PatChartNo,
                     charge,
                     '',
                     ])

    
    if xls:
        data.insert(0, [u'員工代號', u'醫師姓名', u'緊急到院處理事由', u'日期', u'起/迄時間', u'時數', u'病歷號碼', u'應領金額', u'蓋 章'])
        return data_to_xls(data, '%d-%d.xls' % (y, m))
    else:
#         return render_to_response('registry/op_charge.html', 
#                                   {
#                                    'data': data,
#                                    'year': yy,
#                                    'month': mm,
# #                                   'q': q,
#                                    },
#                                   context_instance=RequestContext(request))
        return render(request, 'registry/op_charge.html', 
                                  {
                                   'data': data,
                                   'year': yy,
                                   'month': mm,
                                   })

#fileupload

@login_required
def op_charge1(request):
    
    
    from collections import defaultdict
    dict2d = defaultdict(lambda: defaultdict(int))
    doctors = set()
    years = set()
    
    
    oplist = OPSchedule.objects.filter(Complete='完成').filter(~Q(OpTypeName = '預'))    
#    if q and len(q) > 2:
#        oplist = oplist.filter(content__contains=q)

    xls = request.GET.get('xls', False)
    
    for op in oplist:
        StartTime = datetime.datetime.combine(op.OPDate, op.StartTime)
        EndTime = StartTime + datetime.timedelta(minutes=op.SpendTime)
        
        start, end, charge = handling_charge(StartTime, EndTime)
        if charge:
        
            doctor = op.OpDoctorName
            year = op.OPDate.year
    #         print doctor, year
            doctors.add(doctor)
            years.add(year)
            dict2d[doctor][year] = dict2d[doctor][year] + 1 

    data = []
    
    row = [u'醫師姓名']
    for year in sorted(years)[-5:]:
        row.append(year)
    data.append(row)

    for doctor in sorted(doctors):
        row = [doctor]
        for year in sorted(years)[-5:]:
            row.append(dict2d[doctor][year])
        data.append(row)
    
    if xls:
        return data_to_xls(data, 'op_ch1.xls')
    else:
#         return render_to_response('registry/op_charge1.html', 
#                                   {
#                                    'data': data,
# #                                    'year': yy,
# #                                    'month': mm,
# #                                   'q': q,
#                                    },
#                                   context_instance=RequestContext(request))
        return render(request, 'registry/op_charge1.html', 
                                  {
                                   'data': data,
                                   })



def response_mimetype(request):
    if "application/json" in request.META['HTTP_ACCEPT']:
        return "application/json"
    else:
        return "text/plain"

#class PictureCreateView(CreateView):
#    model = Picture
#
#    def form_valid(self, form):
#        self.object = form.save()
#        f = self.request.FILES.get('file')
#        data = [{'name': f.name, 'url': settings.MEDIA_URL + "pictures/" + f.name.replace(" ", "_"), 'thumbnail_url': settings.MEDIA_URL + "pictures/" + f.name.replace(" ", "_"), 'delete_url': reverse('upload-delete', args=[self.object.id]), 'delete_type': "DELETE"}]
#        response = JSONResponse(data, {}, response_mimetype(self.request))
#        response['Content-Disposition'] = 'inline; filename=files.json'
#        return response

def multiple_uploader(request, PatChartNo, date):
    if request.POST:
        if request.FILES == None:
            raise Http404("No objects uploaded")
        f = request.FILES['file']

        a = Picture()

#        a.creator = request.user
        a.OPDate = date
        a.PatChartNo = PatChartNo

        a.file.save(f.name, f)
        a.save()

        result = [{'name': f.name,
                   'size': f.size,
                   'url': a.file.url,
                 },]

        response_data = json.dumps(result)
        if "application/json" in request.META['HTTP_ACCEPT_ENCODING']:
            mimetype = 'application/json'
        else:
            mimetype = 'text/plain'
        return HttpResponse(response_data, content_type=mimetype)
    else:
        return HttpResponse('Only POST accepted')

#class PictureDeleteView(DeleteView):
#    model = Picture
#
#    def delete(self, request, *args, **kwargs):
#        """
#        This does not actually delete the file, only the database record.  But
#        that is easy to implement.
#        """
#        self.object = self.get_object()
#        self.object.delete()
#        response = JSONResponse(True, {}, response_mimetype(self.request))
#        response['Content-Disposition'] = 'inline; filename=files.json'
#        return response

class JSONResponse(HttpResponse):
    """JSON response class."""
    def __init__(self,obj='',json_opts={},mimetype="application/json",*args,**kwargs):
        content = json.dumps(obj,**json_opts)
        super(JSONResponse,self).__init__(content,mimetype,*args,**kwargs)

def op_picture(request, PatChartNo, date):
    pics = Picture.objects.filter(PatChartNo = PatChartNo, OPDate = date).order_by('id')
    
    # return render_to_response('registry/op_picture.html', 
    #                           {
    #                            'pics': pics,
    #                            },
    #                           context_instance=RequestContext(request))
    return render(request, 'registry/op_picture.html', 
                              {
                               'pics': pics,
                               })

def Default_Dr(request, ChartNo):
    from ntuhgov.portal_selenium import Login, QueryModifyPatBase
    
    pat = QueryModifyPatBase({'ChartNo':ChartNo})
    # print pat
    
    import json
    data = json.dumps(pat)
    
    return HttpResponse(data)
    return HttpResponse('Only POST accepted')
    
