/* DocWindow.m
 * Cenon document window class
 *
 * Copyright (C) 1995-2007 by vhf interservice GmbH
 * Author: Georg Fleischmann
 *
 * Created:  1995-12-02
 * Modified: 2007-05-04
 *
 * info: the first responder of documentWindow is the graphic view (set in document.m)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the vhf Public License as
 * published by vhf interservice GmbH. Among other things, the
 * License requires that the copyright notices and this notice
 * be preserved on all copies.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the vhf Public License for more details.
 *
 * You should have received a copy of the vhf Public License along
 * with this program; see the file LICENSE. If not, write to vhf.
 *
 * vhf interservice GmbH, Im Marxle 3, 72119 Altingen, Germany
 * eMail: info@vhf.de
 * http://www.vhf.de
 */

#include <AppKit/AppKit.h>
#include <VHFShared/types.h>
#include <VHFShared/vhfCommonFunctions.h>
#include <VHFShared/vhf2DFunctions.h>
#include "functions.h"
#include "App.h"
#include "DocView.h"
#include "Document.h"
#include "DocWindow.h"
#include "TilePanel.h"
#include "messages.h"

@implementation DocWindow

/* returns the document of the window
 */
- document
{
    return document;
}

/* sets the document of the window (our private init method)
 * Note: bg-color is the color of the coordinate bar
 */
- (void)setDocument:docu
{
    document = docu;

    [unitPopup selectItemAtIndex:unit];	// init popup
    [unitPopup setTarget:self];
    [unitPopup setAction:@selector(setUnit:)];

    [self setDelegate:document];	// so that the document gets NSWindow delegation methods

    //[self setMiniwindowImage:[NSImage imageNamed:@"typeCenon"]];

#ifdef __linux__
    [self setAcceptsMouseMovedEvents:YES];	// doesn't work on OpenStep, works on GNUstep
#else
    if (!timer)
        timer = [NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(coordTimerFired:) userInfo:nil repeats:YES];	// workaround for OpenStep
#endif
}

- (NSSize)coordBoxSize
{
    return [coordBox borderRect].size;
}

- (BOOL)acceptsFirstResponder
{
    return YES;
}

/* the unit has been changed
 */
- (void)setUnit:sender
{
    unit = [sender indexOfSelectedItem]; 
    [self makeFirstResponder:[document documentView]];
}
- (int)unit
{
    return unit;
}

/* turn on/off coordinate display
 */
- (void)enableCoordDisplay:(BOOL)enable
{   static float	offset = 0.0;
    NSView		*contentView = [self contentView];
    NSRect		frame, tileFrame, boxFrame;

    if (enable == [coordBox isDescendantOf:contentView])
        return;
    frame     = [contentView    frame];
    tileFrame = [tileScrollView frame];
    boxFrame  = [coordBox       frame];
    if (enable)
    {
        [contentView addSubview:coordBox];
        [coordBox release];
        tileFrame.size.height = frame.size.height - offset;
        boxFrame.origin.y     = frame.size.height - offset;
        [tileScrollView setFrame:tileFrame];
        [coordBox       setFrameOrigin:boxFrame.origin];
    }
    else
    {
        offset = frame.size.height - [tileScrollView frame].size.height;
        [coordBox retain];
        [coordBox removeFromSuperview];
        tileFrame.size.height = frame.size.height;
        //boxFrame.origin.y     = frame.size.height;
        [tileScrollView setFrame:tileFrame];
        //[coordBox       setFrameOrigin:boxFrame.origin];
    }
}

- (BOOL)hasCoordDisplay
{
    return ([coordBox isDescendantOf:[self contentView]]);
}

- (void)coordTimerFired:(id)timer
{   NSPoint		pc, p;
    static NSPoint	lastP = {0.0, 0.0};
    NSRect		rect;
    id			view = [document documentView];

    if ( ![self isKeyWindow] )
        return;
    pc = [self mouseLocationOutsideOfEventStream];
    p = [[view superview] convertPoint:pc fromView:nil];
    rect = [(NSClipView*)[view superview] bounds];
    if ( ![view mouse:p inRect:rect] || DiffPoint(lastP, p)<0.001 )
        return;
    lastP = p;
    p = [view convertPoint:pc fromView:nil];
    [self displayCoordinate:p ref:NO];
}

/* display the passed coordinate
 */
- (void)displayCoordinate:(NSPoint)p0 ref:(BOOL)ref
{   NSPoint	p;

    if (ref)
        refPoint = p0;
    p = [[document documentView] pointRelativeOrigin:p0];

    [xCoord setStringValue:buildRoundedString([self convertToUnit:p.x], LARGENEG_COORD, LARGE_COORD)];
    [yCoord setStringValue:buildRoundedString([self convertToUnit:p.y], LARGENEG_COORD, LARGE_COORD)];

    //[distance setStringValue:buildRoundedString(convertToUnit(sqrt((p.x*p.x)+(p.y*p.y))], LARGENEG_COORD, LARGE_COORD)];

    p = p0;
    p.x -= refPoint.x;
    p.y -= refPoint.y;
    [wCoord setStringValue:buildRoundedString([self convertToUnit:p.x], LARGENEG_COORD, LARGE_COORD)];
    [hCoord setStringValue:buildRoundedString([self convertToUnit:p.y], LARGENEG_COORD, LARGE_COORD)];

    if ( [self isAutodisplay] == NO )
        [coordBox display];
}

/*
 * converts a value from internal unit to the current unit
 */
- (float)convertToUnit:(float)value
{
    switch (unit)
    {
        case UNIT_MM:    return (value*25.4/72.0);
        case UNIT_INCH:  return (value / 72.0);
        case UNIT_POINT: return value;
    }
    return (value);
}

/* delegate methods
 * [NSApp mainWindow] may not be set yet !!!
 */
- (void)windowDidBecomeMain:(NSNotification *)notification
{
    [(App*)NSApp displayToolPanel:YES];
    [[NSNotificationCenter defaultCenter] postNotificationName:DocWindowDidChange
                                                        object:document];
    //[[(App*)NSApp tilePanel] updatePanel:self];
}

- (void)windowDidBecomeKey:(NSNotification *)notification
{
    [[(App*)NSApp tilePanel] updatePanel:self];
}

- (void)windowDidResignKey:(NSNotification *)notification
{   //NSWindow *theWindow = [notification object];

    [self endEditingFor:nil];	/* end editing of text */
}

- (void)close
{
    [timer invalidate];
    //NSLog(@"retain=%d", [self retainCount]);
    [[NSNotificationCenter defaultCenter] postNotificationName:DocWindowDidChange
                                                        object:nil];
    [super close];
}

@end
