//
//  SFRulerView.m
//  ShinyRuler
//
//  Created by Matteo rattotti on 12/17/07.
//  Copyright 2007 www.shinyfrog.net. All rights reserved.
//

#import "SFRulerView.h"
#import "SFResizeControl.h"

@implementation SFRulerView

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
    
        // Initializing color and gradient for the bg
        finalColor = [NSColor colorWithCalibratedRed:0.945 green:0.643 blue:0.286 alpha:0.8];
        initialColor = [NSColor colorWithCalibratedRed:0.972 green:0.980 blue:0.458 alpha:0.8];
        bgGradient = [[NSGradient alloc] initWithStartingColor:initialColor endingColor:finalColor];
        
        // Setting orientation mode
        if(frame.size.width > frame.size.height)
            orizontal = 1;
        else
            orizontal = 0;
            
        // Default setting
        markDistance = 2.0;      // Default mark distance   
        markHeight = 3.0;        // Default mark height
        markMediumHeight = 8.0;  // Mid mark height
        markMediumSpace = 10.0;  // Offset of mid mark 
        markBigHeight = 10.0;    // height of marks with number on it
        markBigSpace = 50.0;     // space between marks with number on it
        
        //doubleClickTime = 0.0;
        
        // Adding the resize control view
        NSRect resizeControlFrame;
        if(orizontal)
            resizeControlFrame = NSMakeRect([self frame].size.width -10.0, 0, 10.0, [self frame].size.height);
        else
            resizeControlFrame = NSMakeRect(0, [self frame].size.height -10.0, [self frame].size.width, 10);
        
        res = [[SFResizeControl alloc]initWithFrame:resizeControlFrame];
        [self addSubview:res];
        
        // Setting behaviour when resizing the window
        [self setAutoresizingMask:NSViewMaxXMargin];
    }
    return self;
}

#pragma mark <View Properties>

/* Is a orizontal or a vertical ruler*/
- (BOOL) isOrizontal{
    return orizontal;
}

/* The view is flipped */
- (BOOL)isFlipped{
    return YES;
}

/*
#pragma mark <Managing tracking rect>

- (void)setTrackingRect
{
        trackingRect = [self addTrackingRect:[self visibleRect] 
                                   owner:self 
                                userData:nil 
                            assumeInside:NO];
    
}

- (void)clearTrackingRect
{
	[self removeTrackingRect:trackingRect];
}

- (void)resetCursorRects
{
	[super resetCursorRects];
	[self clearTrackingRect];
	[self setTrackingRect];
}
*/


#pragma mark <Shape functions>

// Return the shape for the ruler
- (NSBezierPath *) rulerShape:(NSRect)rulerRect{

    NSBezierPath *rulerPath = [NSBezierPath bezierPathWithRect:rulerRect];
 
    float borderWidth = 2.0;
 
    [rulerPath setLineWidth:borderWidth];
    return rulerPath;
}

/* Returning mark point for an orizontal or vertical ruler */
- (NSPoint) tickSpace:(float)space tickHeight:(float)height position:(int)position{
    
    // Checking position and changing beaviour as needed
   if (position == SFRulerMarkPositionBottom) 
        height = [self frame].size.height - height;
   else if (position == SFRulerMarkPositionRight)
        height = [self frame].size.width - height;
    
    // Checking what kind of ruler we have
    if ([self isOrizontal]) 
        return NSMakePoint(space, height);
    else 
        return NSMakePoint(height, space);
}

// Return shape with the marks on the ruler
- (NSBezierPath *) rulerMarkShape:(NSRect)rulerRect position:(int)rulerPosition{
    NSBezierPath* markSteps = [NSBezierPath bezierPath];
    float borderWidth = 1.0;
 
    [markSteps setLineWidth:borderWidth];

    int tick;
    int tickWidth;
    
    if([self isOrizontal]) 
        tickWidth = rulerRect.size.width;
    else 
        tickWidth = rulerRect.size.height;
    
    int boffset = markDistance;
    int moffset = markDistance;
    
    
    for(tick=markDistance;tick< tickWidth; tick+=markDistance){
        [markSteps moveToPoint:[self tickSpace:tick tickHeight:0.0 position:rulerPosition]];
        if (boffset == markBigSpace){
            boffset =0;
            moffset = 0;
            [markSteps lineToPoint:[self tickSpace:tick tickHeight:markBigHeight position:rulerPosition]];
            /* TEST CODE */
            /*NSString* string = [NSString stringWithFormat:@"%d", tick];
            NSFont *font = [NSFont fontWithName:@"Monaco" size:12.0];
            
            NSTextView *textview;
            textview = [[NSTextView alloc] init];

            [textview setString: string];
            [textview setFont: font];

            NSLayoutManager *layoutManager;
            layoutManager = [textview layoutManager];

            NSRange range;
            range = [layoutManager glyphRangeForCharacterRange:
                                       NSMakeRange (0, [string length])
                                   actualCharacterRange: NULL];
            NSGlyph *glyphs;
            glyphs = (NSGlyph *) malloc (sizeof(NSGlyph)
                                         * (range.length * 2));
            [layoutManager getGlyphs: glyphs  range: range];
            
            [markSteps moveToPoint:NSMakePoint(tick, markBigHeight+3.0)];
            
            [markSteps appendBezierPathWithGlyphs: glyphs count: range.length  inFont: font];

            free (glyphs);
            [textview release];*/
            /* TEST CODE */
        }
        else if(moffset == markMediumSpace){
            moffset = 0;
            [markSteps lineToPoint:[self tickSpace:tick tickHeight:markMediumHeight position:rulerPosition]];

        }
        else
            [markSteps lineToPoint:[self tickSpace:tick tickHeight:markHeight position:rulerPosition]];

        boffset += markDistance;
        moffset += markDistance;
    }
        
    return markSteps;
}


#pragma mark <Drawing functions>

- (void) drawMarkNumber:(NSRect)rulerRect{
    NSString *number;
    
    /* Setting font and attribute */
    NSMutableDictionary *attributes = [NSMutableDictionary dictionary];
    NSColor *fontColor = [NSColor colorWithCalibratedRed:0.33 green:0.33 blue:0.33 alpha:1.0];
    NSFont *font = [NSFont fontWithName:@"Lucida Grande" size:9.0];
    [attributes setObject:fontColor forKey:NSForegroundColorAttributeName];
    [attributes setObject:font forKey:NSFontAttributeName]; 

    int tick;
    int width;
    NSPoint centerTick;
    
    if([self isOrizontal])
        width = rulerRect.size.width;
    else
        width = rulerRect.size.height;
        
    for(tick=markBigSpace;tick< width; tick+=markBigSpace){
        number = [NSString stringWithFormat:@"%d", tick];
        NSSize numberSize = [number sizeWithAttributes:attributes];
        if([self isOrizontal])
            centerTick = NSMakePoint(tick - numberSize.width/2, rulerRect.size.height / 2 - numberSize.height/2);
        else
            centerTick = NSMakePoint( rulerRect.size.width / 2 - numberSize.width/2, tick - numberSize.height/2);
        [number drawAtPoint:centerTick withAttributes:attributes];
    }
}

- (void)drawRect:(NSRect)rect {    

    [[NSColor grayColor]set];

    NSGraphicsContext* gc =  [NSGraphicsContext currentContext];
    [gc setShouldAntialias:NO];
    
    if([self isOrizontal]){
        [bgGradient drawInRect:rect angle:90.0];
        NSBezierPath *topMarks = [self rulerMarkShape:rect position:SFRulerMarkPositionTop];
        [topMarks stroke];
    
        NSBezierPath *bottomMarks = [self rulerMarkShape:rect position:SFRulerMarkPositionBottom];
        [bottomMarks stroke];
        }
    else{
        [bgGradient drawInRect:rect angle:180.0];

        NSBezierPath *topMarks = [self rulerMarkShape:rect position:SFRulerMarkPositionLeft];
        [topMarks stroke];
    
        NSBezierPath *bottomMarks = [self rulerMarkShape:rect position:SFRulerMarkPositionRight];
        [bottomMarks stroke];

    }
    [gc setShouldAntialias:YES];
    [NSBezierPath strokeRect:rect];
    [self drawMarkNumber:rect];
    
}

#pragma mark <Mouse handling functions>

//- (void) mouseDown:(NSEvent *) event{
//
//     if ([event clickCount] > 1) {
//             NSLog(@"double click");
//             
//              //NSTimeInterval dblTime = (double) GetDblTime() / 60.0;
//             /* NSEvent *nextEvent = [NSApp nextEventMatchingMask: NSLeftMouseDownMask 
//                                            untilDate: nil 
//                                            inMode: NSDefaultRunLoopMode
//                                            dequeue: NO];*/
//              if([event timestamp] - doubleClickTime < 0.6){
//                NSLog(@"suka");
//              }
//              //NSLog(@"%f timestamp", [event timestamp]);
//             else
//                [self rotate];
//             doubleClickTime = [event timestamp];
//
//    } else {
//        //[[self window] setIgnoresMouseEvents:YES];
//        
//        //[ [self window] setAcceptsMouseMovedEvents:YES]; 
//       //[ [self window] makeFirstResponder:self]; 
//         NSLog(@"click");
//
//
//    }
//}


/*- (void)mouseDragged:(NSEvent *)theEvent {
    NSRect resizeSpace = NSMakeRect([self frame].size.width -20.0, 0, 20.0, [self frame].size.height);

    NSLog(@"balozzo %f %f %f %f", resizeSpace.origin.y, resizeSpace.origin.x, resizeSpace.size.height, resizeSpace.size.width);


    NSPoint tempPoint = [self convertPoint:[theEvent locationInWindow] fromView: nil];
    NSLog(@"DRAAAAG %f %f", tempPoint.x, tempPoint.y);
     if(NSPointInRect(tempPoint, resizeSpace)){
        //[[self window] setMovableByWindowBackground:NO];
     }
     else{
     }
}
*/

/*- (void)mouseDragged:(NSEvent*)event
{
    NSRect rect = [self frame];
    rect.origin.x += [event deltaX];
    rect.origin.y -= [event deltaY];
    
    [self setFrame:rect];
    [[self superview] setNeedsDisplay:YES];
    
    [super mouseDragged:event];
}*/
/*
- (void)mouseEntered:(NSEvent *)theEvent 
{
    [[self window] setIgnoresMouseEvents:NO];
    NSLog(@"in");
     //[ [self window] setAcceptsMouseMovedEvents:YES]; 
     //[ [self window] makeFirstResponder:self]; 
} 

- (void)mouseExited:(NSEvent *)theEvent 
{ 
        [[self window] setIgnoresMouseEvents:YES];
    NSLog(@"out");

    //[ [self window] setAcceptsMouseMovedEvents:NO]; 
} 
*/

@end

