/*
 * Copyright (c) 2010 David McIntosh <dmcintosh@df12.net>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#import "GanttRulerView.h"

#define DEBUG_RULERVIEW NO

@implementation GanttRulerView

+ (GanttRulerView *)rulerView
{
    id rule = [[self alloc] init];
    AUTORELEASE(rule);
    return rule;
}

- (void)setZoomFactor:(GanttZoomFactor)zoomFactor
{
    _zoomFactor = zoomFactor;
}

- (void)setOriginDate:(NSDate *)originDate
{
    ASSIGN(_originDate, originDate);
}

- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect
{
    if (DEBUG_RULERVIEW)
        UKLog(@"Called for rect: %@", NSStringFromRect(aRect));

    if ( nil == _originDate )
        return;

    float multiplier = 1.0;
    switch (_zoomFactor)
    {
        case GanttZoomClose:
            multiplier = GanttZoomCloseMult;
            break;
        case GanttZoomMedium:
            multiplier = GanttZoomMediumMult;
            break;
        case GanttZoomWide:
            multiplier = GanttZoomWideMult;
            break;
    }

    // The time interval represented by each notch
    NSTimeInterval notchInterval = GanttDayHours * multiplier * GanttHour;

    NSDate *date = _originDate;
    float notchSpacing = GanttNotchWidth;

    if (DEBUG_RULERVIEW)
        UKLog(@"Origin date: %@", 
            [date descriptionWithCalendarFormat:@"%H:%M %e %b" 
                timeZone:[NSTimeZone systemTimeZone] locale:nil]);

    // Determine what date we should start at for the current scroll loc
    NSPoint docOrigin = 
        [[self scrollView] documentVisibleRect].origin;
    float firstOffset = fmod(docOrigin.x/multiplier, notchSpacing);
    if (DEBUG_RULERVIEW)
        UKLog(@"Offset is %0.2f hours", firstOffset);

    date = [date dateByAddingTimeInterval: -firstOffset*GanttHour*multiplier];
    if (DEBUG_RULERVIEW)
        UKLog(@"subtracted offset.  Now: %@", 
            [date descriptionWithCalendarFormat:@"%H:%M %e %b" 
                timeZone:[NSTimeZone systemTimeZone] locale:nil]);
    date = [date dateByAddingTimeInterval: (docOrigin.x)*(GanttHour)];
    date = [date dateByRoundingToNearest: GanttHour];
    if (DEBUG_RULERVIEW)
        UKLog(@"Starting at: %@", 
            [date descriptionWithCalendarFormat:@"%H:%M %e %b" 
                timeZone:[NSTimeZone systemTimeZone] locale:nil]);

    // date = [date dateByAddingTimeInterval: (docOrigin.x-firstOffset)*(GanttHour)];

    float thickness = [self ruleThickness];

    NSRect notch = NSMakeRect(
        (-firstOffset), (thickness * 0.45),
        1.0, (thickness * 0.38));

    CGFloat labelFSize = [NSFont smallSystemFontSize] * 0.7;
    CGFloat mLabelFSize = [NSFont smallSystemFontSize] * 0.7;
    NSPoint labelOrigin = 
        NSMakePoint( (-firstOffset + 3.0), 
            (thickness * 0.6) - mLabelFSize);
    NSPoint mLabelOrigin = 
        NSMakePoint( (-firstOffset + 3.0) , 
            (thickness * 0.6) - (labelFSize + mLabelFSize));

    // The notch label
    NSString *label = nil;
    NSDictionary *attr = [NSDictionary 
        dictionaryWithObject:[NSFont systemFontOfSize:labelFSize]
        forKey:NSFontAttributeName];

    // The month label
    NSString *mLabel = nil;
    NSDictionary *mAttr = [NSDictionary 
        dictionaryWithObject:[NSFont systemFontOfSize:mLabelFSize]
        forKey:NSFontAttributeName];

    // store the previous label to ensure we don't use the same one twice
    NSString *prev = nil;

    [[NSColor blackColor] set];

    while ( notch.origin.x < aRect.size.width )
    {
        // UKLog(@"Date: %@", date);
        prev = label;
        
        label = [date descriptionWithCalendarFormat:@"%e" 
            timeZone:[NSTimeZone systemTimeZone] locale:nil];

        mLabel = [date descriptionWithCalendarFormat:@"%b" 
            timeZone:[NSTimeZone systemTimeZone] locale:nil];
        
        if (![label isEqualToString:prev])
        {
            [label drawAtPoint:labelOrigin withAttributes:attr];
            if ([label isEqualToString:@"1"] || nil == prev)
                [mLabel drawAtPoint:mLabelOrigin withAttributes:mAttr];
        }
        if (notch.origin.x > 0.0)
            NSRectFill(notch);
        notch.origin.x += notchSpacing;
        labelOrigin.x += notchSpacing;
        mLabelOrigin.x += notchSpacing;
        date = [date dateByAddingTimeInterval:notchInterval];
    }

    NSRectFill(NSMakeRect(0, thickness * 0.75, aRect.size.width, 1.0));

}

- (void)dealloc
{
    DESTROY(_originDate);
    [super dealloc];
}

@end
