/* TilePanel.m
 * Panel for batch production
 *
 * Copyright (C) 1996-2014 by Cenon GmbH
 * Author:   Georg Fleischmann
 *
 * created:  1996-04-10
 * modified: 2014-10-21 (-relativeDistance, -updatePanel:, ..., tileXYDirections)
 *           2013-01-22 (-relativeDistance, -updatePanel:, ..., tileDistance , min/max)
 *           2008-07-19 (Document Units)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the Cenon Public License as
 * published by Cenon 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 Cenon Public License for more details.
 *
 * You should have received a copy of the Cenon Public License along
 * with this program; see the file LICENSE. If not, write to Cenon.
 *
 * Cenon GmbH, Schwabstr. 45, 72108 Rottenburg a.N., Germany
 * eMail: info@Cenon.com
 * http://www.cenon.com
 */

#include <AppKit/AppKit.h>
#include <VHFShared/VHFSystemAdditions.h>
#include <VHFShared/vhfCommonFunctions.h>
#include "App.h"
#include "TilePanel.h"
#include "functions.h"
#include "DocView.h"

@interface TilePanel(PrivateMethods)
@end

@implementation TilePanel

- (BOOL)useAbsoluteDistance
{
    return ( [distPopup indexOfSelectedItem] == 0 ) ? NO : YES;
}
- (void)setDistancePopup:sender
{   static int  prevSelectedItem = 0;
    Document    *doc = [(App*)NSApp currentDocument];
    DocView     *view = [doc documentView];
    float       min = [doc convertToUnit:-99999.0], max = [doc convertToUnit:99999.0];
    NSSize      size = [view tileBounds].size;
    NSPoint     d = [self distance];
    NSString    *string;
    
    if ([distPopup indexOfSelectedItem] == prevSelectedItem)
        return;
    switch ([distPopup indexOfSelectedItem])
    {
            case 0:	// absolute -> relative
                string = buildRoundedString([doc convertToUnit:(d.x-size.width)], min, max);
                [[distanceMatrix cellAtRow:0 column:0] setStringValue:string];
                string = buildRoundedString([doc convertToUnit:(d.y-size.height)], min, max);
                [[distanceMatrix cellAtRow:1 column:0] setStringValue:string];
            break;
        case 1:	// relative -> absolute
                string = buildRoundedString([doc convertToUnit:(d.x+size.width)], min, max);
                [[distanceMatrix cellAtRow:0 column:0] setStringValue:string];
                string = buildRoundedString([doc convertToUnit:(d.y+size.height)], min, max);
                [[distanceMatrix cellAtRow:1 column:0] setStringValue:string];
    }
    prevSelectedItem = [distPopup indexOfSelectedItem];

    [self updatePanel:self]; // to display the new values
}
-(IBAction)setXYDirections:(id)sender
{
    if ([[[(NSButton*)sender image] name] isEqual:@"arrowRight"])
        [(NSButton*)sender setImage:[NSImage imageNamed:@"arrowLeft"]];
    else if ([[[(NSButton*)sender image] name] isEqual:@"arrowLeft"])
        [(NSButton*)sender setImage:[NSImage imageNamed:@"arrowRight"]];
    else if ([[[(NSButton*)sender image] name] isEqual:@"arrowUp"])
        [(NSButton*)sender setImage:[NSImage imageNamed:@"arrowDown"]];
    else if ([[[(NSButton*)sender image] name] isEqual:@"arrowDown"])
        [(NSButton*)sender setImage:[NSImage imageNamed:@"arrowUp"]];
    
    [self set:self];
}

- (NSPoint)xyDirections
{   NSPoint     xyDirs = NSMakePoint(1.0, 1.0);

    if ([[[xDirButton image] name] isEqual:@"arrowLeft"])
        xyDirs.x = 0.0;
    if ([[[yDirButton image] name] isEqual:@"arrowDown"])
        xyDirs.y = 0.0;

    return xyDirs;
}

- (BOOL)limitSize
{
    return ( [limitsPopUp indexOfSelectedItem] == 0 ) ? NO : YES;
}

- (NSPoint)limits
{   Document    *doc = [(App*)NSApp currentDocument];
    NSPoint     p;

    p.x = [[limitsMatrix cellAtRow:0 column:0] floatValue];
    p.y = [[limitsMatrix cellAtRow:1 column:0] floatValue];
    if ( [self limitSize] )
    {   p.x = [doc convertFrUnit:p.x];
        p.y = [doc convertFrUnit:p.y];
    }

    return p;
}

- (BOOL)mustMoveMasterToOrigin
{
    return ( [(NSButton*)originSwitch state] == 0 ) ? NO : YES;
}

/* return the Value in the TilePanel - nothing else */
- (NSPoint)distance
{   Document    *doc = [(App*)NSApp currentDocument];
    NSPoint     p;
    float       min = -99999.0, max = 99999.0;

    p.x = [doc convertFrUnit:[[distanceMatrix cellAtRow:0 column:0] floatValue]];
    p.y = [doc convertFrUnit:[[distanceMatrix cellAtRow:1 column:0] floatValue]];

    /* min max check ! ! ! */
    if (p.x < min ) p.x = min;
    if (p.x > max ) p.x = max;
    if (p.y < min ) p.y = min;
    if (p.y > max ) p.y = max;

    return p;
}

/*
 * calculate the correct tileDistance corresponding to xyDirections
 * this value will be saved in DocView
 */
- (NSPoint)relativeDistance
{   DocView	*view  = [[(App*)NSApp currentDocument] documentView];
    NSSize	size   = [view tileBounds].size;
    NSPoint	p      = [self distance];

    /* distance value is absolut */
    if ([distPopup indexOfSelectedItem] == 1) // absolute
    {
        /* change distance to positive - so negative values if Value is smaller size */
        p.x = Abs(p.x);
        p.y = Abs(p.y);

        if (p.x <= TOLERANCE) // we dont accept 0
            p.x = size.width;
        if (p.y <= TOLERANCE)
            p.y = size.height;

        p.x = p.x-size.width;
        p.y = p.y-size.height;
    }
    else // distance value is relativ
    {
        if ( p.x < 0.0 ) // negativ until size for inside moving, but not 0
            p.x = (Abs(p.x) > size.width +TOLERANCE) ? (Abs(p.x)) : ((Diff(Abs(p.x),  size.width) < TOLERANCE) ? (0.0) : (p.x));
        if ( p.y < 0.0 )
            p.y = (Abs(p.y) > size.height+TOLERANCE) ? (Abs(p.y)) : ((Diff(Abs(p.y), size.height) < TOLERANCE) ? (0.0) : (p.y));
    }
    return p;
}

- (void)createTilesAsCopy:(BOOL)buildCopy
{   Document    *doc = [(App*)NSApp currentDocument];
    DocView     *view = [doc documentView];
    NSSize      viewSize = [view bounds].size;
    NSPoint     dist         = [self relativeDistance], limits = [self limits];
    NSPoint     dirs         = [self xyDirections];
    BOOL        limitSize    = [self limitSize];
    BOOL        moveToOrigin = [self mustMoveMasterToOrigin];

    /* check input */
    if ( [self limitSize] )
    {
        if ( viewSize.width<limits.x || viewSize.height<limits.y )
        {
            [[limitsMatrix cellAtRow:0 column:0] setStringValue:
                buildRoundedString([doc convertToUnit:limits.x], 0.0, [doc convertToUnit:viewSize.width])];
            [[limitsMatrix cellAtRow:1 column:0] setStringValue:
                buildRoundedString([doc convertToUnit:limits.y], 0.0, [doc convertToUnit:viewSize.height])];
            return;
        }
    }
    else
    {
    }

    if ( buildCopy )
        [view   buildTileCopies:limits limitSize:limitSize distance:dist directions:dirs moveToOrigin:moveToOrigin];
    else
        [view setTileWithLimits:limits limitSize:limitSize distance:dist directions:dirs moveToOrigin:moveToOrigin];

    [self updatePanel:self];
}

/*
 * modified: 1997-03-02
 */
- (void)set:sender
{
    [self createTilesAsCopy:NO];
}

/*
 * modified: 1997-03-02
 */
- (void)buildCopies:sender
{
    [self createTilesAsCopy:YES];
}

/*
 * modified: 1997-03-02
 */
- (void)removeTiles:sender
{
    [[[(App*)NSApp currentDocument] documentView] removeTiles];
}

/*
 * updatePanel: is used to copy the existing situation into the Tile panel
 * modified: 2014-10-21 (tileXYDirections)
 *           2008-07-19 (Document Units)
 */
- (void)updatePanel:sender
{   Document    *doc = ([sender isKindOfClass:[DocWindow class]])
                       ? [sender document] : [(App*)NSApp currentDocument];
    DocView     *view = [doc documentView];
    NSPoint     p, pDirs;
    float       min = [doc convertToUnit:-99999.0], max = [doc convertToUnit:99999.0];
    NSSize      size = [view tileBounds].size;

    /* tile distance */
    p = [view tileDistance];            // this is always relative
    pDirs = [view tileXYDirections];	// weather we go to right/left up/down
    if ([distPopup indexOfSelectedItem] == 1)	// absolute distance
        p = NSMakePoint(p.x+size.width, p.y+size.height);

    [[distanceMatrix cellAtRow:0 column:0] setStringValue:buildRoundedString([doc convertToUnit:p.x], min, max)];
    [[distanceMatrix cellAtRow:1 column:0] setStringValue:buildRoundedString([doc convertToUnit:p.y], min, max)];

    /* update limits from panel - change of limit */
    if ( [sender isKindOfClass:[NSPopUpButton class]] )
    {
        // FIXME: pay attention to twist of selectedItem here ! it returns the old state!
    }
    /* Update limits from view - for window change or something like this */
    else
    {
        /* tile limits by size of material */
        if ( [view tileLimitSize] )
        {   NSPoint	lim = [view tileLimits];

            if ( [view tileLimitSize] )
                lim = NSMakePoint( [doc convertToUnit:lim.x],   [doc convertToUnit:lim.y] );
            else
                lim = NSMakePoint( [doc convertMMToUnit:100.0], [doc convertMMToUnit:100.0] );

            [[limitsMatrix cellAtRow:0 column:0] setStringValue:buildRoundedString(lim.x, min, max)];
            [[limitsMatrix cellAtRow:1 column:0] setStringValue:buildRoundedString(lim.y, min, max)];
            [limitsPopUp selectItemAtIndex:1];
        }
        /* tile limits by number of items */
        else
        {   NSPoint	lim = (![view tileLimitSize]) ? [view tileLimits] : NSMakePoint( 2.0, 2.0 );

            if ( !lim.x || !lim.y )
                lim = NSMakePoint( 2.0, 2.0 );
            [[limitsMatrix cellAtRow:0 column:0] setIntValue:(int)lim.x];
            [[limitsMatrix cellAtRow:1 column:0] setIntValue:(int)lim.y];
            [limitsPopUp selectItemAtIndex:0];
        }
    }

    if (pDirs.x)
        [xDirButton setImage:[NSImage imageNamed:@"arrowRight"]];
    else
        [xDirButton setImage:[NSImage imageNamed:@"arrowLeft"]];
    if (pDirs.y)
        [yDirButton setImage:[NSImage imageNamed:@"arrowUp"]];
    else
        [yDirButton setImage:[NSImage imageNamed:@"arrowDown"]];
}

@end
