//
//  OmPlaceEdit.m
//  OmLoc
//
//  Created by david van brink on 8/1/10.
//  Copyright 2010 omino.com. All rights reserved.
//

#import "OmPlaceEdit.h"
#import "OmCoreGraphicsUtils.h"
#import "OmUiUtils.h"
#include "OmLocColors.h"


enum
{
    B_OK = 11,
    B_DEL,
    B_PREV,
    B_NEXT
};

#define PE_MARGIN 18

#define RT 320
#define BT 480

#define PE_THUMBNAIL_LEFT 0
#define PE_THUMBNAIL_TOP 0
#define PE_THUMBNAIL_WIDTH 200
#define PE_THUMBNAIL_HEIGHT 200
#define PE_THUMBNAIL_BOTTOM (PE_THUMBNAIL_TOP + PE_THUMBNAIL_HEIGHT)

#define PE_INFO_LEFT (PE_THUMBNAIL_LEFT + PE_MARGIN)
#define PE_INFO_RIGHT (RT - PE_MARGIN)
#define PE_INFO_TOP (PE_THUMBNAIL_BOTTOM + PE_MARGIN)
#define PE_INFO_HEIGHT 22
#define PE_INFO_BOTTOM (PE_INFO_TOP + PE_INFO_HEIGHT)

#define PE_ICONS_TOP 0
#define PE_ICONS_LEFT (PE_THUMBNAIL_LEFT + PE_THUMBNAIL_WIDTH)
#define PE_ICONS_WIDTH (320 - PE_ICONS_LEFT)

#define PE_DESC_LEFT PE_MARGIN
#define PE_DESC_TOP (PE_INFO_BOTTOM + PE_MARGIN)
#define PE_DESC_WIDTH (RT - 2 * PE_MARGIN)
#define PE_DESC_HEIGHT 22

#define PE_MCTR_LEFT PE_MARGIN
#define PE_MCTR_TOP (PE_DESC_TOP + PE_DESC_HEIGHT + PE_MARGIN)
#define PE_MCTR_WIDTH 20
#define PE_MCTR_HEIGHT 20

#define PE_LL_LEFT PE_MARGIN
#define PE_LL_Y (BT - 80)
#define PE_LL_FONTSIZE 12

// +----------------------------
// | prototypes
// +----------------------------

static void drawCheckbox(CGContextRef g,int x,int y,int w,int h,int state, NSString *label);
static int touchInCheckbox(NSSet *touches,UIView *v,int x,int y,int w,int h);
void readFromPlace(OmPlaceEdit *pe);


@implementation OmPlaceEdit

- (id)initWithFrame:(CGRect)frame 
{
    
    if ((self = [super initWithFrame:frame]))
    {
        OmCellPicker *cp = &self->icons;
        cp->top = PE_ICONS_TOP;
        cp->left = PE_ICONS_LEFT;
        cp->right = PE_ICONS_LEFT + PE_ICONS_WIDTH;
        cp->cellsPerRow = 3;
        cp->cellCount = MARKER_COUNT;
        
        
        
        
        [self setBgRgb:0x808090];

        UITextField *tf = [[UITextField alloc] init];
        [tf setFrame:CGRectMake(PE_DESC_LEFT,PE_DESC_TOP,PE_DESC_WIDTH,PE_DESC_HEIGHT)];
        
        tf.placeholder = @"(what is this place?)";
        
        tf.textColor = GColor(CO_LABEL_TEXT);
        tf.backgroundColor = GColor(CO_TEN_MINUTE_CIRCLE);
        tf.autocorrectionType = UITextAutocorrectionTypeNo;
        tf.returnKeyType = UIReturnKeyDone;
        [self addSubview:tf];
        tf.delegate = self;
        
        self->descriptionTf = tf;

        // we already appointed the Place, to txt it up.
//        OmWayPoint *p = [self->placeList getWayPoint:self->placeIndex];
        
#define BW 60
#define BH 40
        CGRect r = CGRectMake(RT - BW - PE_MARGIN,BT - BH - PE_MARGIN,BW,BH);
        [self addButton:@"DONE" tag:B_OK rect:r];
        r.origin.x -= BW + PE_MARGIN;
        [self addButton:@"->" tag:B_NEXT rect:r];
        r.origin.x -= BW + PE_MARGIN;
        [self addButton:@"<-" tag:B_PREV rect:r];
        
#define DBW 40
#define DBH 40
        r = CGRectMake(PE_MARGIN,BT - BH - PE_MARGIN,DBW,DBH);
        UIButton *delB = [self addButton:@"DEL" tag:B_DEL rect:r];
//        [delB setBackgroundColor:GColor(CO_DANGEROUS_BUTTON)];
        [delB setTitleColor:GColor(CO_DANGEROUS_BUTTON) forState:UIControlStateNormal];
        
        readFromPlace(self);
        
    }
    return self;
}

// populate the controls from current place index
void readFromPlace(OmPlaceEdit *pe)
{
    OmWayPoint *p = [pe->placeList getWayPoint:pe->placeIndex];
    pe->icons.selected = p->marker;
    pe->descriptionTf.text = p->desc;
}

- (void) setPlaceList:(OmPlacesList *)newPlaceList index:(int)newPlaceIndex
{
    self->placeList = newPlaceList;
    self->placeIndex = newPlaceIndex;
    readFromPlace(self);
}

- (void)finishItAllUp:(bool)doSave
{
    OmWayPoint *p = [self->placeList getWayPoint:self->placeIndex];
    p->marker = self->icons.selected;
    NSString *desc = self->descriptionTf.text;
    setWayPointDescription(p,desc);
    if(doSave)
        [self->placeList saveToFile];
}


- (void)drawRect:(CGRect)rect 
{
    CGContextRef g = UIGraphicsGetCurrentContext();
    G(g);
    GFillRectR(g, [self bounds], CO_ONE_MINUTE_CIRCLE);
    GSetFillColor(g,CO_LABEL_TEXT);
    
//    GPrintf(g,3,215,"description");
    
    OmWayPoint *p = [self->placeList getWayPoint:self->placeIndex];
    CGRect thr = CGRectMake(PE_THUMBNAIL_LEFT,PE_THUMBNAIL_TOP,PE_THUMBNAIL_WIDTH,PE_THUMBNAIL_HEIGHT);
    if(p->image)
    {
        [p->image drawInRect:thr];
    }
    else
        GFillRectR(g, thr, CO_MISSING_COLOR);
    // label, anyway
    int fsize = 15;
    GSetFont(g,1,fsize);
    GSetFillColor(g,CO_LABEL_TEXT);
    GPrintf(g,PE_INFO_LEFT,PE_INFO_TOP + fsize,"%s, %d of %d",p->timeDescription,self->placeIndex + 1,[self->placeList getWayPointCount]);
    
    // show the available markers...
    {
        float maxScale = 2;
        
        CGRect selectedMarkerR = getOmCellRect(&self->icons, self->icons.selected);
        GFillRectR(g, selectedMarkerR, CO_SELECTED_MARKER);
        
        for(int i = 0; i < MARKER_COUNT; i++)
        {
            UIImage *marker = omMarkers[i];
            CGRect cellRect = getOmCellRect(&self->icons,i);
            CGSize markerSize = [marker size];
            float scale = cellRect.size.width / markerSize.width;
            if(scale > maxScale)
                scale = maxScale;
            float drawW = markerSize.width * scale;
            float drawH = markerSize.height * scale;
            CGRect drawRect = CGRectMake(cellRect.origin.x + (cellRect.size.width - drawW) / 2,
                       cellRect.origin.y + (cellRect.size.height - drawH) / 2,
                       drawW,
                       drawH);
            [marker drawInRect:drawRect];
        }
    }
    
    // show the latlon
    {
        GSetFillColor(g,0);
        GSetFont(g, 2, PE_LL_FONTSIZE);
        OmWayPoint *p = [self->placeList getWayPoint:self->placeIndex];
        GPrintf(g, PE_LL_LEFT, PE_LL_Y, "lat:%.5f lon:%.5f",p->lat,p->lon);
    }
    
    // show the checkbox state
    {
        int checked = self->placeIndex == [self->placeList getMapCenter];
        drawCheckbox(g, PE_MCTR_LEFT, PE_MCTR_TOP, PE_MCTR_WIDTH, PE_MCTR_HEIGHT, checked, @"use as map center");
    }
}

static bool tryPicker(OmPlaceEdit *ope,NSSet *touches)
{
    bool result = false;
	UITouch *touch = [touches anyObject];
    CGPoint pt = [touch locationInView:ope];
    int cell = getOmCellIndex(&ope->icons, pt);
    if(cell >= 0)
    {
        if(cell != ope->icons.selected)
        {
            ope->icons.selected = cell;
            [ope repaint];
        }
        result = true;
    }
    return result;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    bool didPickIcon = tryPicker(self,touches);
    if(didPickIcon)
        return;
    
    if(touchInCheckbox(touches,self,PE_MCTR_LEFT,PE_MCTR_TOP,PE_MCTR_WIDTH,PE_MCTR_HEIGHT))
    {
        int checked = self->placeIndex == [self->placeList getMapCenter];
        int newCtr = self->placeIndex;
        if(checked)
            newCtr = -1;

        [self->placeList setMapCenter:newCtr];
        [self repaint];
    }
}

- (void) buttonAction:(UIButton *)sender
{
    int tag = [sender tag];
    if(tag == B_OK)
    {
        [self finishItAllUp:true];
        [self dismiss];
    }
    if(tag == B_DEL)
    {
        self->deletePlaceActionSheet = OmActionAskNoYes(self, @"Cancel", @"Delete", "Permanently delete place %d?",self->placeIndex);
    }
    if(tag == B_PREV || tag == B_NEXT)
    {
        [self finishItAllUp:false];
        int n = self->placeIndex + (tag == B_PREV ? -1 : 1);
        int cnt = [self->placeList getWayPointCount];
        n = (n + cnt) % cnt;
        self->placeIndex = n;
        readFromPlace(self);
        [self repaint];
    }
}
    

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    bool didPickIcon = tryPicker(self,touches);
    if(didPickIcon)
        return;

    return;
}
- (void)dealloc {
    [super dealloc];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [self->descriptionTf resignFirstResponder];
    return YES;
}

// Animation code copied, directly, and without modification,
// from http://stackoverflow.com/questions/1247113/iphone-keyboard-covers-text-field 
// awesome.

- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
    const int movementDistance = 80; // tweak as needed
    const float movementDuration = 0.3f; // tweak as needed
    
    int movement = (up ? -movementDistance : movementDistance);
    
    [UIView beginAnimations: @"anim" context: nil];
    [UIView setAnimationBeginsFromCurrentState: YES];
    [UIView setAnimationDuration: movementDuration];
    self.frame = CGRectOffset(self.frame, 0, movement);
    [UIView commitAnimations];
}


- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self animateTextField: textField up: YES];
}


- (void)textFieldDidEndEditing:(UITextField *)textField
{
    [self animateTextField: textField up: NO];
}


// for handling modal dialogs
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    // 0 means destruct, 1 meant cancel, for an action sheet
    if(actionSheet == self->deletePlaceActionSheet)
    {
        if(buttonIndex == 0) // yes!
        {
            [self->placeList clear:self->placeIndex];
            [self->placeList saveToFile];
            [self dismiss];
        }
        self->deletePlaceActionSheet = nil;
    }
}



@end


CGRect getOmCellRect(OmCellPicker *cp,int cellNumber)
{
    float cellSize = (cp->right - cp->left) / cp->cellsPerRow;

    int row = cellNumber / cp->cellsPerRow;
    int col = cellNumber % cp->cellsPerRow;
    CGRect result;
    result.origin.x = cp->left + col * cellSize;
    result.origin.y = cp->top + row * cellSize;
    result.size.width = cellSize;
    result.size.height = cellSize;
    return result;
}

int getOmCellIndex(OmCellPicker *cp,CGPoint p)
{
    float cellSize = (cp->right - cp->left) / cp->cellsPerRow;
    int col = (p.x - cp->left) / cellSize;
    int row = (p.y - cp->top) / cellSize;
    if(col < 0 || col >= cp->cellsPerRow)
        return -1;
    int result = row * cp->cellsPerRow + col;
    if(result < 0 || result >= cp->cellCount)
        result = -1;
    return result;
}

static void drawCheckbox(CGContextRef g,int x,int y,int w,int h,int state,NSString *label)
{
    CGRect r = CGRectMake(x,y,w,h);
    GSetFillColor(g,CO_ONE_MINUTE_CIRCLE);
    GFillRectR(g, r, CO_ONE_MINUTE_CIRCLE);
    GFrameRectR(g, r, 2, CO_TEN_MINUTE_CIRCLE);
    if(state)
    {
        CGContextMoveToPoint(g, x, y);
        CGContextAddLineToPoint(g, x + w, y + h);
        CGContextMoveToPoint(g, x + w, y);
        CGContextAddLineToPoint(g, x, y + h);
        GSetStrokeColor(g,CO_TEN_MINUTE_CIRCLE);
        CGContextStrokePath(g);
    }
    GSetFillColor(g, CO_TEN_MINUTE_CIRCLE);
    GSetFillColor(g, CO_LABEL_TEXT);
    GSetFont(g, 3, h - 4);
    NSSTRING_TO_C(label,cLabel);
    GPrintf(g,x + w + w/2,y + h * 3 / 4,"%s",cLabel);
}


static int touchInCheckbox(NSSet *touches,UIView *v,int x,int y,int w,int h)
{
    int slop = (w + h) / 3;
    int result = touchInRect(touches,v,x - slop,y - slop,w + slop + slop,h + slop + slop);
    return result;
}



