# coding=utf-8
# Create your views here.

import datetime, re
import mx.DateTime

from django.contrib import auth
from django.contrib.auth.decorators import login_required
from django.core import serializers
from django.core.mail import send_mail
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from django.db.models import *
from django.http import Http404, HttpResponse, HttpResponseRedirect
#from django.newforms import form_for_instance
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils import simplejson
from django.views.generic import *

from forms import *
from models import *

import intra


@login_required
def patient_add(request):
    if request.method == 'POST':
        force = True
        result = intra.Default_Dr(request.POST)
    else:
        chartno = request.GET.get('ChartNo', '')
        name = request.GET.get('Name', '')
        idcode = request.GET.get('idcode', '')
        force = request.GET.get('force', '')
        result = intra.Default_Dr({'ChartNo': chartno,
                                   'Name': name,
                                   'idcode': idcode,
                                   })

    if force and len(result)==1:
        r=result[0]
        if r['gender'] == 'M':
            r['gender'] = 1
        else:
            r['gender'] = 2
        hw = intra.HeightWeight(r['id_cards'])
        p = Patient(name = r['name'],
                    medical_records = r['medical_records'],
                    gender = r['gender'],
                    birthday = r['birthday'],
                    address = r['address'],
                    phone = r['phone'],
                    id_cards = r['id_cards'],
                    height = hw['Height'],
                    weight = hw['Weight'],
		   )
        p.save()
        return HttpResponseRedirect('/patient/detail/%d/' % p.id)

    form = PatientForm()
    return render_to_response('ck/patient_add.html',
                              {
                               'form': form,
                               'result': result,
                               }, context_instance=RequestContext(request))

@login_required
def patient_detail(request, object_id):
    if object_id=='':
        object_id = request.session.get('patient')
    patient = Patient.objects.get(id=object_id)
    if object_id:
        qset = (
            Q(patient=object_id)
        )
        treatments = Treatment.objects.filter(qset).distinct()
    else:
        treatments = []

# update patient timestamp

#    ts = patient.timestamp.date()
#    for treatment in treatments:
#        if treatment.date_completed > ts:
#            ts = treatment.date_completed
#    if patient.timestamp.date() != ts:
#        patient.timestamp = datetime.datetime.combine(ts, patient.timestamp.time())
#        patient.save()

    pacsimages = PACSImage.objects.filter(Q(patient=object_id),Q(Modality__startswith='CT')|Q(Modality__startswith='MR')).order_by('-ExamDate')
    if len(pacsimages) > 9:
        pacsimages = pacsimages[0:9]

    response = render_to_response("ck/patient_detail.html",
                              {
                               "patient": patient,
                               "treatments": treatments,
                               "pacsimages": pacsimages,
                              }, context_instance=RequestContext(request))
    response.set_cookie('patient', object_id)
    request.session['patient'] = object_id
    return response

@login_required
def patient_follow(request):
    pass


@login_required
def patient_print(request, object_id):
    if object_id=='':
        object_id = request.session.get('patient')
    patient = Patient.objects.get(id=object_id)
    if object_id:
        qset = (
            Q(patient=object_id)
        )
        treatments = Treatment.objects.filter(qset).distinct()
    else:
        treatments = []

# update patient timestamp

#    ts = patient.timestamp.date()
#    for treatment in treatments:
#        if treatment.date_completed > ts:
#            ts = treatment.date_completed
#    if patient.timestamp.date() != ts:
#        patient.timestamp = datetime.datetime.combine(ts, patient.timestamp.time())
#        patient.save()

    response = render_to_response("ck/patient_print.html",
                              {
                               "patient": patient,
                               "treatments": treatments,
                              }, context_instance=RequestContext(request))
    response.set_cookie('patient', object_id)
    request.session['patient'] = object_id
    return response


@login_required
def patient_search(request):
    query = request.GET.get('q', '')
    if query:
        qset = (
            Q(medical_records__icontains=query) |
            Q(name__icontains=query) |
            Q(id_cards__icontains=query)
        )
        results = Patient.objects.filter(qset).distinct()
        if len(results) == 0:
            if re.match('^\d+', query):
                return HttpResponseRedirect('/patient/add/?ChartNo='+query)
            elif re.match('^\w\d+', query):
                return HttpResponseRedirect('/patient/add/?idcode='+query)
            else:
                return HttpResponseRedirect('/patient/add/?Name='+query)
    else:
        results = []
#    print "query=", query
#    print "results=", results
    return render_to_response("ck/patient_search.html",
                              {
                               "results": results,
                               "query": query,
                              }, context_instance=RequestContext(request))


@login_required
def prior_oncrt_query(request, object_id):
    if object_id=='':
        object_id = request.session.get('patient')
    patient = Patient.objects.get(id=object_id)
    priors = patient.priortreatment_set;

    answers = intra.oncrt_query(patient.medical_records)

#    return HttpResponse(str(answers))

    for answer in answers:
        if answer['way'] != 'Radiosurgery' and not priors.filter(date=answer['start_date']):
            p = PriorTreatment(
                patient = patient,
                date = answer['start_date'],
                treatment = 3,
                period = 1,
                dose = answer['total_dose'],
                memo = answer['site'] + ' ' + answer['remarks'],
            )
            p.save()
    return HttpResponseRedirect('/patient/detail/'+object_id)


@login_required
def prior_op_note(request, object_id):
    if object_id=='':
        object_id = request.session.get('patient')
    patient = Patient.objects.get(id=object_id)
    priors = patient.priortreatment_set;

    answers = intra.op_note_case(patient.medical_records)

#    return HttpResponse(str(answers))

    for answer in answers:
        if not priors.filter(date=answer['surgery_date_time']):
            p = PriorTreatment(
                patient = patient,
                date = answer['surgery_date_time'],
                treatment = 1,
                memo = ' '.join([answer['division'], answer['name_surgery'], answer['surgeon']])
            )
            p.save()
    return HttpResponseRedirect('/patient/detail/'+object_id)

@login_required
def prior_path_exam(request, object_id):
    if object_id=='':
        object_id = request.session.get('patient')
    patient = Patient.objects.get(id=object_id)
    pathexams = patient.pathexam_set;

    answers = intra.path_exam(patient.medical_records)

#    return HttpResponse(str(answers))

    for answer in answers:
        if not pathexams.filter(path_code=answer['path_code']):
            p = PathExam(
                    patient           = patient,
		    path_code         = answer['path_code'],
		    specimen_code     = answer['specimen_code'],
		    specimen_get_date = answer['specimen_get_date'],
		    report_date       = answer['report_date'],
		    division          = answer['division'],
		    bed               = answer['bed'],
		    report            = answer['report'],
		)

            p.save()
    return HttpResponseRedirect('/patient/detail/'+object_id)

@login_required
def query_height_weight(request, object_id):
    if object_id=='':
        object_id = request.session.get('patient')
    patient = Patient.objects.get(id=object_id)
    hw = intra.HeightWeight(patient.id_cards)
    patient.height = hw['Height']
    patient.weight = hw['Weight']
    patient.save()

    return HttpResponseRedirect('/patient/detail/'+object_id)


@login_required
def record_weekly(request, date):
    if not date:
        date = mx.DateTime.today()

    Monday = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=-6,weekday=(mx.DateTime.Monday,0))
    NextMonday = Monday + mx.DateTime.RelativeDateTime(days=+7)
    prevweek = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=-7)
    nextweek = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=+7)

    weekday = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']

    weekdate = {}
    d = Monday
    for day in weekday:
        weekdate[day] = d.strftime('%m/%d')
        d = d + mx.DateTime.RelativeDateTime(days=+1)

#    print NextMonday, NNMonday
    qset1 = Q(DTSTART__range=(Monday, NextMonday))

    qset2 = Q(mode__exact=310) #310: 治療

    events = VEVENT.objects.filter(qset1, qset2).order_by('DTSTART')

    tids = []

    for event in events:
        tid = event.treatment.id
        if not tid in tids:
            tids.append(tid)

    treatments = []
    for tid in tids:
        t = Treatment.objects.get(id=tid);
        treatment = {
            'id': t.id,
            'icd9': t.icd9,
            'other_diagnosis': t.other_diagnosis,
            'accounting': t.get_accounting_display(),
            'dates': [],
            'surgeon': t.surgeon,
            'oncologist': t.oncologist,
            'referral': t.referral,
        }

        for event in events:
            if tid == event.treatment.id:
                treatment['dates'].append(event.DTSTART.date())

#        for lesion in Treatment.objects.get(id=tid).lesion_set:
#            treatment.


        treatments.append(treatment)



#    treatments = Treatment.objects.filter(id__in=tids)

    response = render_to_response("ck/record_weekly.html",
                              {
                               "prevweek": prevweek.date,
                               "nextweek": nextweek.date,
                               "weeknumber": Monday.strftime('%G年 第%V週'),
                               "weekdate": weekdate,
                               "events": events,
                               "treatments": treatments,
                              }, context_instance=RequestContext(request))
    return response


@login_required
def timetable_scheduling(request, date):
    if not date:
        date = mx.DateTime.today()

    Monday = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=+6,weekday=(mx.DateTime.Monday,0))
    NextMonday = Monday + mx.DateTime.RelativeDateTime(days=+7)
    prevweek = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=-7)
    nextweek = mx.DateTime.DateTimeFrom(date) + mx.DateTime.RelativeDateTime(days=+7)
#    print NextMonday, NNMonday
    qset = (
        Q(DTSTART__range=(Monday, NextMonday))
    )

    treatments = Treatment.objects.filter(output__id__lt=900)

    weekday = ['mon', 'tue', 'wed', 'thu', 'fri']

    weekdate = {}
    d = Monday
    for day in weekday:
        weekdate[day] = d.strftime('%m/%d')
        d = d + mx.DateTime.RelativeDateTime(days=+1)

    timetable = []
    for treatment in treatments:
        if treatment.vevent_set.filter(qset):
            r = {}
            patient = treatment.patient
            r['name'] = patient.name
            r['medical_records'] = patient.medical_records
            r['indications'] = str(treatment.surgeon) + '\n' + str(treatment.oncologist)
            r['diagnosis_site'] = treatment.other_diagnosis
            r['number'] = ''
            r['node'] = ''
            r['mode'] = ''
            r['time'] = ''
            r['actual_treatment'] = ''
            for day in weekday:
                r[day] = ''
            for event in treatment.vevent_set.order_by('DTSTART'):
                wd = (event.DTSTART.date() - datetime.datetime.fromtimestamp(Monday).date()).days
                if wd in range(0, 6):
                    r[weekday[wd]] += event.DTSTART.strftime('%H:%M') + ' ' + event.get_mode_display() + '\n'
            timetable.append(r)


#        print timetable

    response = render_to_response("ck/timetable_scheduling.html",
                              {
                               "prevweek": prevweek.date,
                               "nextweek": nextweek.date,
                               "timetable": timetable,
                               "weekdate": weekdate,
                              }, context_instance=RequestContext(request))
    return response


@login_required
def treatment_detail(request, object_id):
    if object_id=='':
        object_id = request.session.get('treatment')
    treatment = Treatment.objects.get(id=object_id)
    patient = Patient.objects.get(id=treatment.patient_id)
#    response.set_cookie('patient', patient.id)
    request.session['patient'] = patient.id
    if object_id:
        qset = (
            Q(treatment=object_id)
        )
        vevents = VEVENT.objects.filter(qset).distinct().order_by('DTSTART')
        lesions = Lesion.objects.filter(qset).distinct()
    else:
        vevents = []
        lesions = []

# update treatment date_completed

    for vevent in vevents:
        vevent.SUMMARY = vevent.treatment.patient.name + vevent.get_mode_display()
        vevent.save()

    ds = False
    dc = False

    for lesion in lesions:
        if lesion.start_date != None:
          if not ds or lesion.start_date < ds:
            ds = lesion.start_date
	if lesion.end_date != None:
          if not dc or lesion.end_date > dc:
            dc = lesion.end_date

    if not ds:
        for vevent in vevents:
            if vevent.mode != 310:
                continue
            if not ds or vevent.DTSTART.date() < ds:
                ds = vevent.DTSTART.date()
            if not dc or vevent.DTSTART.date() > dc:
                dc = vevent.DTSTART.date()

    if not ds:
        for vevent in vevents:
            if not ds or vevent.DTSTART.date() < ds:
                ds = vevent.DTSTART.date()
            if not dc or vevent.DTSTART.date() > dc:
                dc = vevent.DTSTART.date()

    if ds and treatment.date_started != ds:
        treatment.date_started = ds
        treatment.save()
    if dc and treatment.date_completed != dc:
        treatment.date_completed = dc
        treatment.save()


    response = render_to_response("ck/treatment_detail.html",
                              {
                               "patient": patient,
                               "treatment": treatment,
                               "vevents": vevents,
                               "lesions": lesions,
                              }, context_instance=RequestContext(request))
    response.set_cookie('patient', patient.id)
    request.session['patient'] = patient.id
    response.set_cookie('treatment', object_id)
    request.session['treatment'] = object_id
    return response


@login_required
def treatment_print(request, object_id):
    if object_id=='':
        object_id = request.session.get('treatment')
    treatment = Treatment.objects.get(id=object_id)
    patient = Patient.objects.get(id=treatment.patient_id)
    if object_id:
        qset = (
            Q(treatment=object_id)
        )
        vevents = VEVENT.objects.filter(qset).distinct().order_by('DTSTART')
        lesions = Lesion.objects.filter(qset).distinct()
    else:
        vevents = []
        lesions = []

# update treatment date_completed

    dc = treatment.date_completed

    for vevent in vevents:
        vevent.SUMMARY = vevent.treatment.patient.name + vevent.get_mode_display()
        vevent.save()
        if vevent.DTSTART.date() > dc:
            dc = vevent.DTSTART.date()

    if treatment.date_completed != dc:
        treatment.date_completed = dc
        treatment.save()

    paginator = Paginator(lesions, 3) # Show 3 lesions per page

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        contacts = paginator.page(page)
    except (EmptyPage, InvalidPage):
        contacts = paginator.page(paginator.num_pages)

    response = render_to_response("ck/treatment_print.html",
                              {
                               "patient": patient,
                               "treatment": treatment,
                               "vevents": vevents,
                               "contacts": contacts,
                              }, context_instance=RequestContext(request))
    response.set_cookie('patient', object_id)
    request.session['patient'] = object_id
    response.set_cookie('treatment', object_id)
    request.session['treatment'] = object_id
    return response


@login_required
def treatment_record(request, object_id):
    if object_id=='':
        object_id = request.session.get('treatment')
    treatment = Treatment.objects.get(id=object_id)
    patient = Patient.objects.get(id=treatment.patient_id)
    if object_id:
        qset = (
            Q(treatment=object_id)
        )
        vevents = VEVENT.objects.filter(qset).distinct().order_by('DTSTART')
        lesions = Lesion.objects.filter(qset).distinct()
    else:
        vevents = []
        lesions = []

# update treatment date_completed

    dc = treatment.date_completed

    for vevent in vevents:
        vevent.SUMMARY = vevent.treatment.patient.name + vevent.get_mode_display()
        vevent.save()
        if vevent.DTSTART.date() > dc:
            dc = vevent.DTSTART.date()

    if treatment.date_completed != dc:
        treatment.date_completed = dc
        treatment.save()

#    response = render_to_response("ck/treatment_record.html",
    response = render_to_response("ck/brief_history.html",

                              {
                               "patient": patient,
                               "treatment": treatment,
                               "vevents": vevents,
                               "lesions": lesions,
                              }, context_instance=RequestContext(request))
    response.set_cookie('patient', object_id)
    request.session['patient'] = object_id
    response.set_cookie('treatment', object_id)
    request.session['treatment'] = object_id
    return response


@login_required
def treatment_report(request, object_id):
    if object_id=='':
        object_id = request.session.get('treatment')
    treatment = Treatment.objects.get(id=object_id)
    patient = Patient.objects.get(id=treatment.patient_id)
    if object_id:
        qset = (
            Q(treatment=object_id)
        )
        vevents = VEVENT.objects.filter(qset).distinct().order_by('DTSTART')
        lesions = Lesion.objects.filter(qset).distinct()
    else:
        vevents = []
        lesions = []

# update treatment date_completed

    dc = treatment.date_completed

    for vevent in vevents:
        vevent.SUMMARY = vevent.treatment.patient.name + vevent.get_mode_display()
        vevent.save()
        if vevent.DTSTART.date() > dc:
            dc = vevent.DTSTART.date()

    if treatment.date_completed != dc:
        treatment.date_completed = dc
        treatment.save()

    paginator = Paginator(lesions, 5) # Show 25 contacts per page

    # Make sure page request is an int. If not, deliver first page.
    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    # If page request (9999) is out of range, deliver last page of results.
    try:
        contacts = paginator.page(page)
    except (EmptyPage, InvalidPage):
        contacts = paginator.page(paginator.num_pages)

    response = render_to_response("ck/treatment_report.html",
                              {
                               "patient": patient,
                               "treatment": treatment,
                               "vevents": vevents,
                               "contacts": contacts,
                              }, context_instance=RequestContext(request))
    response.set_cookie('patient', object_id)
    request.session['patient'] = object_id
    response.set_cookie('treatment', object_id)
    request.session['treatment'] = object_id
    return response


@login_required
def treatment_update(request, object_id):
    if request.method == 'POST':
#        TreatmentForm = form_for_model(Treatment)
        form = TreatmentForm(request.POST)
        form.save()
        return HttpResponseRedirect('/treatment/list/')

    treatment = Treatment.objects.get(id=object_id)
    patient = Patient.objects.get(id=treatment.patient.id)
#    TreatmentForm = form_for_instance(treatment)
    form = TreatmentForm(instance=treatment)
    response = render_to_response("ck/treatment_form2.html",
                              {
                               "form": form,
                               "patient": patient,
                              }, context_instance=RequestContext(request))
    response.set_cookie('treatment', object_id)
    request.session['treatment'] = object_id
    return response


@login_required
def followup_newimages(request):
#    date_start = Treatment.objects.values('patient_id').annotate(date=Min('date_started'))
#    print date_start.query
#    print date_start

    date_query = Treatment.objects.values('patient_id').annotate(started=Min('date_started'),completed=Max('date_completed'))
#    print date_query.query
#    print date_query
    
    images = PACSImage.objects.filter(Q(Saved = 0),Q(Modality__startswith='CT')|Q(Modality__startswith='MR')).order_by('-ExamDate')
#    images = PACSImage.objects.get(Q(modality='CT')|Q(modality__startswith='MR'))
#    print images
    
    results = []
    
    blank = 0
    
    for image in images:
        if blank > 50:
            break
        try:
            treat_date = date_query.get(patient=image.patient)
        except:
            continue
#        print image.ExamDate, image.patient.id, treat_date
        if image.ExamDate > treat_date['completed']:
            try:
                LF = LesionFollow.objects.get(Q(Lesion__treatment__patient = image.patient),Q(Date = image.ExamDate))
                image.Saved = 10 #有輸入
            except:
                pass
                
#            print image.patient.name, image.ExamDate
            results.append(image)
            if image.Saved == 0:
                blank += 1 
                
                
    return render_to_response("ck/followup_newimages.html",
                              {
                               "images": results,
                              }, context_instance=RequestContext(request))

@login_required
def followup_markimages(request, RequestSheetNo, Saved):
    image = PACSImage.objects.get(Q(RequestSheetNo = RequestSheetNo))
    image.Saved = Saved
    image.save()
    return HttpResponseRedirect('/followup/newimages/')

@login_required
def followup_nosee1(request):
    treatment_date = Treatment.objects.values('patient_id').annotate(first=Min('date_started'),last=Max('date_completed'))
    followup_date  = Followup.objects.values('patient_id').annotate(first=Min('date'),last=Max('date'))
    record_date    = MedicalRecord.objects.values('patient_id').annotate(first=Min('InDate'),last=Max('InDate'))
    image_date     = PACSImage.objects.values('patient_id').annotate(first=Min('ExamDate'),last=Max('ExamDate'))
    
    patients = Patient.objects.all()
    results = []
#    n = datetime.datetime.now()
    for patient in patients:
        if patient.dead:
            continue
        
        try:
            d = treatment_date.get(patient=patient)
            date = d['last']
        except:
#            print "%s no treatment" % patient.id
            continue

        try:
            d = followup_date.get(patient=patient)
            if d['last'] > date:
                date = d['last']
        except:
#            print "%s no follow" % patient.id
            pass

        try:
            d = record_date.get(patient=patient)
            if d['last'] > date:
                date = d['last']
        except:
#            print "%s no record" % patient.id
            pass

        try:
            d = image_date.get(patient=patient)
            if d['last'] > date:
                date = d['last']
        except:
#            print "%s no image" % patient.id
            pass
        
#        results['patient.id']=date
        results.append((patient, date))
        
#    print results
    results = sorted(results, key=lambda last: last[1])[:25]
#    print datetime.datetime.now() - n
#    print results
        
    return render_to_response("ck/followup_nosee.html",
                              {
                               "results": results,
                              }, context_instance=RequestContext(request))

@login_required
def followup_nosee(request):
    ###Load all dates into hash first
    treatment_date = Treatment.objects.values('patient_id').annotate(first=Min('date_started'),last=Max('date_completed'))
    t = {}
    for item in treatment_date:
        t[item['patient_id']] = item['last']
        
    followup_date  = Followup.objects.values('patient_id').annotate(first=Min('date'),last=Max('date'))
    f = {}
    for item in followup_date:
        f[item['patient_id']] = item['last']
        
    record_date    = MedicalRecord.objects.values('patient_id').annotate(first=Min('InDate'),last=Max('InDate'))
    r = {}
    for item in record_date:
        r[item['patient_id']] = item['last']
        
    image_date     = PACSImage.objects.values('patient_id').annotate(first=Min('ExamDate'),last=Max('ExamDate'))
    i = {}
    for item in image_date:
        i[item['patient_id']] = item['last']
    
    patients = Patient.objects.all()
    results = []
#    n = datetime.datetime.now()
    for patient in patients:
        if patient.dead:
            continue
        
        try:
            d = t[patient.id]
            date = d
        except:
#            print "%s no treatment" % patient.id
            continue

        try:
            d = f[patient.id]
            if d > date:
                date = d
        except:
#            print "%s no follow" % patient.id
            pass

        try:
            d = r[patient.id]
            if d > date:
                date = d
        except:
#            print "%s no record" % patient.id
            pass

        try:
            d = i[patient.id]
            if d > date:
                date = d
        except:
#            print "%s no image" % patient.id
            pass
        
#        results['patient.id']=date
        results.append((patient, date))
        
#    print results
    results = sorted(results, key=lambda last: last[1])[:25]
#    print datetime.datetime.now() - n
#    print results

    model      = Patient
    form_class = None
    model, form_class = create_update.get_model_and_form_class(model, form_class)
    form = form_class()
        
    return render_to_response("ck/followup_nosee.html",
                              {
                               "results": results,
                               "form": form,
                              }, context_instance=RequestContext(request))

@login_required
def followup_image_long(request):
    ###Load all dates into hash first
    treatment_date = Treatment.objects.values('patient_id').annotate(first=Min('date_started'),last=Max('date_completed'))
    t = {}
    for item in treatment_date:
        t[item['patient_id']] = item['first']
        
    image_date     = PACSImage.objects.filter(Saved__in=[0,10]).values('patient_id').annotate(first=Min('ExamDate'),last=Max('ExamDate'))
    i = {}
    for item in image_date:
        i[item['patient_id']] = item['last']

    v = {}
    follows = LesionFollow.objects.select_related().all()
#    print follows
    for follow in follows:
        if not v.has_key(follow.Lesion.treatment.patient.id):
            v[follow.Lesion.treatment.patient.id] = follow.Date
        else:
            v[follow.Lesion.treatment.patient.id] = max(follow.Date, v[follow.Lesion.treatment.patient.id])
        
#    print v


    
#    patients = Patient.objects.select_related().all()
    patients = Patient.objects.all()
    
    results = []
#    n = datetime.datetime.now()
#    print t
#    print i 
    for patient in patients:
        if patient.dead:
            continue
        
        try:
            d = t[patient.id]
            tdate = d
        except:
#            print "%s no treatment" % patient.id
            continue

        try:
            d = i[patient.id]
            idate = d
        except:
#            print "%s no image" % patient.id
            continue
        
        daydiff = (idate-tdate).days
        if daydiff < 365:
            continue
        
        try:
            d = v[patient.id]
            vdate = d
        except:
#            print "%s no image" % patient.id
            vdate = ''
            
        
        
#        results['patient.id']=date
        results.append((patient, daydiff, tdate, idate, vdate))
        
#    print type(idate-tdate)
#    print results
    results = sorted(results, key=lambda last: -last[1])
#    print datetime.datetime.now() - n
#    print results

#    model      = Patient
#    form_class = None
#    model, form_class = create_update.get_model_and_form_class(model, form_class)
#    form = form_class()
        
    return render_to_response("ck/followup_image_long.html",
                              {
                               "results": results,
#                               "form": form,
                              }, context_instance=RequestContext(request))


@login_required
def followup_new_volume(request,object_id):
#    print request
#    print 'object_id=', object_id    
    
    idate = ''

    p = request.POST
#    print p
    if p.has_key('Lesion'):
        lesion = Lesion.objects.get(id=p['Lesion'])
        
        f = lambda x:None if x == '' else x
        
        l = LesionFollow(
            Lesion = lesion,
            Date = p['Date'],
            Volume = f(p['Volume']),
            A = f(p['A']),
            B = f(p['B']),
            C = f(p['C']),
            Memo = p['Memo'],
           )
        l.save()
        idate = p['Date']
        
    try:
        idate = request.GET['idate']
    except:
        idate = request.COOKIES['date']
    
    try:        
        patient = Patient.objects.get(id=object_id)
    except:
        patient = Patient.objects.get(id=request.COOKIES['patient'])

    model      = LesionFollow
    form_class = None
    model, form_class = create_update.get_model_and_form_class(model, form_class)
    form = form_class()
    
    response = render_to_response("ck/followup_new_volume.html",
                              {
                               "patient": patient,
                               "idate": idate,
                               "form": form,
                              }, context_instance=RequestContext(request))
    response.set_cookie('patient', patient.id)
    response.set_cookie('date', idate)
    return response

    


########## AJAX

@login_required
def below(request):
    return render_to_response('ck/below.html')

@login_required
def get_target_location(request):
#    return HttpResponse(serializers.serialize("xml", TargetLocation.objects.all()))
    return HttpResponse(serializers.serialize("json", TargetLocation.objects.all()))

@login_required
def get_sublocation(request):
    i = request.GET.get('id', '')
    if i:
        return HttpResponse(serializers.serialize("json", SubLocation.objects.filter(id=i)))
    target = request.GET.get('target', '')
    return HttpResponse(serializers.serialize("json", SubLocation.objects.filter(target_location=target)))

@login_required
def get_pathology(request):
    sl = request.GET.get('sublocation', '')
    return HttpResponse(serializers.serialize("json", Pathology.objects.filter(sublocation=sl)))

def get_icd9cm(request):
    id = request.GET.get('id', False)
    name = request.GET.get('q', '')
    limit = request.GET.get('s', 99)

    if (name.count('.')):
        name = name.replace('.', '')[0:5].rstrip()
    if id:
        codes = ICD9Diag.objects.filter(code=id)
    elif len(name):
        qset = (
            Q(code__istartswith=name) |
#            Q(code__istartswith='0'+name) |
#            Q(code__istartswith='00'+name) |
            Q(desc__icontains=name)
        )
        codes = ICD9Diag.objects.filter(qset)[:100]
    else:
        codes =ICD9Diag.objects.all()[:100]
        
    ret = """
[  
"""
    
#    ret = '{"results":['  

    for code in codes:
#        ret += '["%s","%s"],' % (code.code, code)
        ret += '["%s","%s"],' % (code, code.code)
#        ret += '\n{"id":"%s","name":"%s"},' % (code.code, code)


    ret = ret[:-1]+"""
]  
"""


    return HttpResponse(ret)


def get_icd9cm_old(request):
    id = request.GET.get('id', False)
    name = request.GET.get('name', '')[:-1]
    if (name.count('.')):
        name = name.replace('.', '')[0:5].rstrip()
    if id:
        codes = ICD9Diag.objects.filter(code=id)
    elif len(name):
        qset = (
            Q(code__istartswith=name) |
#            Q(code__istartswith='0'+name) |
#            Q(code__istartswith='00'+name) |
            Q(desc__icontains=name)
        )
        codes = ICD9Diag.objects.filter(qset)[:100]
    else:
        codes =ICD9Diag.objects.all()[:100]
        
    ret = """
{ 'identifier': 'code',
  'label': 'name',
  'items': [
"""
    
#    ret = '{"results":['  

    for code in codes:
        ret += '\n{"code":"%s","name":"%s"},' % (code.code, code)
#        ret += '\n{"id":"%s","name":"%s"},' % (code.code, code)


    ret = ret[:-1]+"]}"


    return HttpResponse(ret)


def get_followup(request):
    date = request.GET.get('date', '')
    if date:
        d = mx.DateTime.DateTimeFrom(date)
        fr = d + mx.DateTime.RelativeDateTime(weeks=-6)
        to = d + mx.DateTime.RelativeDateTime(weeks=+6)
        events = Patient.objects.filter(next_followup__range=(fr, to))
    else:
        events = Patient.objects.all()

    return HttpResponse(serializers.serialize("json", events, ensure_ascii=False))


def get_vevent_old(request):
    date = request.GET.get('date', '')
    if date:
        d = mx.DateTime.DateTimeFrom(date)
        fr = d + mx.DateTime.RelativeDateTime(weeks=-6)
        to = d + mx.DateTime.RelativeDateTime(weeks=+6)
        events = VEVENT.objects.filter(DTSTART__range=(fr, to))
    else:
        events = VEVENT.objects.all()

    return HttpResponse(serializers.serialize("json", events, ensure_ascii=False))

'''
DataDumper
'''

import types
from django.db import models
import pyxslt.serialize
from django.utils import simplejson as json
from django.core.serializers.json import DateTimeAwareJSONEncoder
from decimal import *

class DataDumper:
    fields = {}
    def selectObjectFields(self,objectType,fields = []):
        self.fields[objectType] = fields

    def dump(self,data,format='xml'):
        """
        The main issues with django's default json serializer is that properties that
        had been added to a object dynamically are being ignored (and it also has 
        problems with some models).
        """
    
        def _any(data):
            ret = None
            if type(data) is types.ListType:
                ret = _list(data)
            elif type(data) is types.DictType:
                ret = _dict(data)
            elif isinstance(data, Decimal):
                # json.dumps() cant handle Decimal
                ret = str(data)
            elif isinstance(data, models.query.QuerySet):
                # Actually its the same as a list ...
                ret = _list(data)
            elif isinstance(data, models.Model):
                ret = _model(data)
            else:
                ret = data
            return ret
        
        def _model(data):
            ret = {}
            # If we only have a model, we only want to encode the fields.
            objType = data.__class__.__name__
            for f in data._meta.fields:
                if (self.fields[objType]) and (f.attname in self.fields[objType]):
                    ret[f.attname] = _any(getattr(data, f.attname))
            # And additionally encode arbitrary properties that had been added.
            fields = dir(data.__class__) + ret.keys()
            add_ons = [k for k in dir(data) if k not in fields]
            for k in add_ons:
                if (self.fields[objType]) and (k in self.fields[objType]):
                    ret[k] = _any(getattr(data, k))
            return ret
        def _list(data):
            ret = []
            for v in data:
                ret.append(_any(v))
            return ret
        
        def _dict(data):
            ret = {}
            for k,v in data.items():
                ret[k] = _any(v)
            return ret
        
        ret = _any(data)
        if(format == 'xml'):
            return pyxslt.serialize.toString(prettyPrintXml=False,data=ret,)
        else:
             return json.dumps(ret, cls=DateTimeAwareJSONEncoder)

'''
DataDumper
'''

@login_required
def get_vevent(request):
    events = VEVENT.objects.extra(select={
        'title' : "SUMMARY",
        'allDay': "false",
#        'start' : "UNIX_TIMESTAMP(DATE_SUB(DTSTART, INTERVAL 8 HOUR))",
#        'end' : "UNIX_TIMESTAMP(ADDTIME(DATE_SUB(DTSTART, INTERVAL 8 HOUR),DURATION))",
        'start' : "UNIX_TIMESTAMP(DTSTART)",
        'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,DURATION))",
#        'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,DURATION))",
#        'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,MAX(DURATION,'00:30:00')))",
        'url'   : "CONCAT('/event/update/',id,'/')",
    })

    start = request.GET.get('start', '')
    end   = request.GET.get('end'  , '')

    if start:
        fr = datetime.datetime.fromtimestamp(float(start))
        to = datetime.datetime.fromtimestamp(float(end))
        events = events.filter(DTSTART__range=(fr, to))

    dumper = DataDumper()
    dumper.selectObjectFields('VEVENT', ['id', 'title', 'allDay', 'start', 'end', 'url'])
    dumper.dump(events,'json')

    return HttpResponse(dumper.dump(events,'json'))

#    return HttpResponse(serializers.serialize("json", events, ensure_ascii=False))

#    entries = []
#    for event in events:
#        starttime = mx.DateTime.DateTimeFrom(event.DTSTART.isoformat())
#        duration = mx.DateTime.DateTimeDeltaFrom(hours=event.DURATION.hour, minutes=event.DURATION.minute)
#        endtime = starttime + duration
#        entry = {
#            'id': event.id,
#            'starttime': starttime.strftime('%Y-%m-%dT%H:%M:%S'),
#            'endtime': starttime.strftime('%Y-%m-%dT%H:%M:%S'),
#            'allday': False,
#            'repeated': False,
#            'title': event.treatment.patient.name + event.get_mode_display(),
#            'url': "/treatment/detail/%i/" % event.treatment.id,
#            'body': event.SUMMARY,
#            'attributes': {
#                'Oncologist': event.treatment.oncologist.name,
#                'Surgeon': event.treatment.surgeon.name,
#            },
#            'type': [event.get_mode_display(), event.get_mode_display()]
#        }
#        entries.append(entry)
#    return HttpResponse(serializers.serialize("xml", entries, ensure_ascii=False))

@login_required
def event_drop(request):

    id          = request.GET.get('id'         , '')
    dayDelta    = int(request.GET.get('dayDelta'   , ''))
    minuteDelta = int(request.GET.get('minuteDelta', ''))

    vevent = VEVENT.objects.get(id=id)
    t = vevent.DTSTART
    start = mx.DateTime.DateTime(t.year,t.month,t.day,t.hour,t.minute,t.second+1e-6*t.microsecond)
    start = start + mx.DateTime.RelativeDateTime(days=dayDelta) + mx.DateTime.RelativeDateTime(minutes=minuteDelta)
    vevent.DTSTART = datetime.datetime.fromtimestamp(start)
    vevent.save()

    return HttpResponse(serializers.serialize("json", VEVENT.objects.filter(id=id), ensure_ascii=False))

@login_required
def event_resize(request):

    id          = request.GET.get('id'         , '')
    dayDelta    = int(request.GET.get('dayDelta'   , ''))
    minuteDelta = int(request.GET.get('minuteDelta', ''))

    vevent = VEVENT.objects.get(id=id)
    t = vevent.DURATION
    d = datetime.timedelta(days=dayDelta,minutes=minuteDelta)
    dt = datetime.datetime.combine(datetime.date.today(), t) + d
    vevent.DURATION = dt.time()
    vevent.save()

    return HttpResponse(serializers.serialize("json", VEVENT.objects.filter(id=id), ensure_ascii=False))

@login_required
def update_vevent(request):

#    id = request.GET.get('id', '')
#    starttime = request.GET.get('starttime', '')
#    endtime = request.GET.get('endtime', '')

    id = request.POST.get('id', '')
    starttime = mx.DateTime.DateTimeFrom(request.POST.get('starttime', '')[:-6])
    endtime = mx.DateTime.DateTimeFrom(request.POST.get('endtime', '')[:-6])
    duration = mx.DateTime.Age(endtime, starttime)
    duration = str(duration.hours)+':'+str(duration.minutes)

    print id, starttime, endtime, duration

    vevent = VEVENT.objects.get(id=id)
    vevent.DTSTART = starttime
#    vevent.DURATION = duration
    vevent.save()

    return HttpResponse(serializers.serialize("json", VEVENT.objects.filter(id=id), ensure_ascii=False))
#    return HttpResponse("")


def listCalendarByRange(sd, ed, cnt):
#    print ret
#    $title = array('team meeting', 'remote meeting', 'project plan review', 'annual report', 'go to dinner');
#    $location = array('Lodan', 'Newswer', 'Belion', 'Moore', 'Bytelin');
  
  
    events = VEVENT.objects.extra(select={
        'title' : "SUMMARY",
        'allDay': "false",
#        'start' : "UNIX_TIMESTAMP(DATE_SUB(DTSTART, INTERVAL 8 HOUR))",
#        'end' : "UNIX_TIMESTAMP(ADDTIME(DATE_SUB(DTSTART, INTERVAL 8 HOUR),DURATION))",
        'start' : "UNIX_TIMESTAMP(DTSTART)",
        'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,DURATION))",
#        'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,DURATION))",
#        'end' : "UNIX_TIMESTAMP(ADDTIME(DTSTART,MAX(DURATION,'00:30:00')))",
        'url'   : "CONCAT('/event/update/',id,'/')",
    })

    events = events.filter(DTSTART__range=(sd, ed))
#    print events
    
    revents = []
        
    for event in events:
        d = event.DURATION
        revent = (event.id, 
                  event.title, 
                  event.DTSTART.isoformat(), 
                  (event.DTSTART+datetime.timedelta(minutes=d.minute, hours=d.hour)).isoformat(), 
                  0, #IsAllDayEvent
                  0, #more than one day event
                  0, #Recurring event
                  event.id % 14, #Color
                  1, #editable
                   dict(event.MODE_CHOICES).get(event.mode,''), #Location 
                  '', #attends                  
                  )
        print revent
        revents.append(revent)
        
    ret = {}
    ret['events'] = revents
    ret["issort"] = True
    ret["start"] = sd.isoformat()
    ret["end"] = ed.isoformat()
    ret['error'] = None
    
    return ret


def listCalendar(day, type):
    date = datetime.datetime.strptime(day, '%m/%d/%Y')
    print date
    if type == 'month':
        st = date - datetime.timedelta(31)
        et = date + datetime.timedelta(31)
        cnt = 50
    elif type == 'week':
        st = date - datetime.timedelta(7)
        et = date + datetime.timedelta(7)
        cnt = 20
    elif type == 'day':
        st = date - datetime.timedelta(1)
        et = date + datetime.timedelta(1)
        cnt = 5
    
    return listCalendarByRange(st, et, cnt)

#@login_required
def datafeed(request):

    try:

    #    print request
        method = request.GET['method']
    #    print method
        
        if method == 'add':
            pass
        elif method == 'list':
            ret = listCalendar(request.POST['showdate'], request.POST['viewtype'])
        elif method == 'update':
            pass
        elif method == 'remove':
            pass
        elif method == 'adddetails':
            pass
        
    except:
        ret = listCalendar('8/3/2011', 'month')
        
    dumper = DataDumper()
    return HttpResponse(dumper.dump(ret,'json'))


