/* Author Cristian Cserveny, 1994.
   Converted to the OpenStep version by Ovidiu Predescu, 1997.
*/

#import <AppKit/AppKit.h>
#import "InfoView.h"

#define PERIOD		0.005
#define TILES		16
#define GENERATOR	14
#define SMALLMARG	1
#define BIGMARG		2

@implementation InfoView

- (void)awakeFromNib
{
  NSRect rect = [self bounds];
  NSImage* appImage = [NSApp applicationIconImage];
  NSSize size;

  images = [NSMutableArray new];
  [images addObject:appImage];

  size = [appImage size];
  point.x = (rect.size.width - size.width) / 2;
  point.y = (rect.size.height - size.height) / 2;
  xTile = (rect.size.width - SMALLMARG - BIGMARG) / TILES;
  yTile = (rect.size.height - SMALLMARG - BIGMARG) / TILES;

  resultImage = [[NSImage alloc] initWithSize:rect.size];
  [resultImage lockFocus];
  PSsetgray(NSLightGray);
  NSRectFill(rect);
  rect.origin.x++;
  rect.size.height--;
  rect.size.width--;
  PSsetgray(NSBlack);
  NSRectFill(rect);
  rect.origin.x--;
  rect.origin.y++;
  PSsetgray(NSWhite);
  NSRectFill(rect);
  [appImage compositeToPoint:point operation:NSCompositeSourceOver];
  [resultImage unlockFocus];

  currentImageIndex = 1;
}

- (void)dealloc
{
  [images release];
  [resultImage release];
  [super dealloc];
}

- (void)showImageNumber:(int)index
{
  if (index < 0 || index >= [images count] || imagesToDisplay)
    return;

  currentImageIndex = index;
  tickNo = 1;
  imagesToDisplay = 1;
  [NSTimer scheduledTimerWithTimeInterval:PERIOD
                                   target:self
                                 selector:@selector(animateOneImage:)
                                 userInfo:nil
                                  repeats:YES];
}

- (void)showAllImages
{
  if ([images count] <= 1 || imagesToDisplay)
    return;

  imagesToDisplay = [images count];
  tickNo = 1;
  [NSTimer scheduledTimerWithTimeInterval:PERIOD
                                   target:self
                                 selector:@selector(animateAllImages:)
                                 userInfo:nil
                                  repeats:NO];
}

- (void)mouseDown:(NSEvent*)event
{
  if (!imagesToDisplay)
    [self showAllImages];
}

- (void)addImageNamed:(NSString*)imageName
{
  NSBundle* bundle = [NSBundle bundleForClass:isa];
  NSString* path = [bundle pathForResource:imageName ofType:@"tiff"];
  NSImage* image = [[[NSImage alloc] initWithContentsOfFile:path]
    autorelease];

  [self addImage:image];
}

- (void)addImage:(NSImage*)image
{
//  NSRect rect = { NSZeroPoint, [image size] };

  [image lockFocus];
//  PSsetgray(NSWhite);
//  NSRectFill(rect);
  [image compositeToPoint:NSZeroPoint operation:NSCompositeSourceOver];
  [image unlockFocus];

  [images addObject:image];
}

- (void)drawRect:(NSRect)frame
{
  [resultImage compositeToPoint:NSZeroPoint operation:NSCompositeCopy];
}

- (void)animateOneImage:(NSTimer*)timer
{
  id image = [images objectAtIndex:currentImageIndex];
  NSRect rect;
  NSPoint targetPoint;

  tickNo = tickNo * GENERATOR % (TILES * TILES + 1);
  [resultImage lockFocus];
  rect.origin.x = (tickNo % TILES) * xTile + SMALLMARG;
  rect.origin.y = (tickNo / TILES) * yTile + BIGMARG;
  rect.size.width = xTile;
  rect.size.height = yTile;
  targetPoint.x = point.x + rect.origin.x;
  targetPoint.y = point.y + rect.origin.y;

  if(tickNo == 1) {
    [timer invalidate];
    tickNo = 0;
    rect.origin = NSZeroPoint;
    rect.size = [image size];
    rect.origin = point;
    PSsetgray(NSWhite);
    NSRectFill(rect);
    [image compositeToPoint:point operation:NSCompositeSourceOver];

    currentImageIndex++;
    if (currentImageIndex == [images count])
      currentImageIndex = 0;
    imagesToDisplay--;
  }
  else
    [image compositeToPoint:targetPoint
                   fromRect:rect
                  operation:NSCompositeSourceOver];

  [resultImage unlockFocus];
  [self display];
}

- (void)animateAllImages:(NSTimer*)timer
{
  if (tickNo)
    [self animateOneImage:timer];

  /* Schedule a new timer if we still have to display parts of the current image. */
  if (tickNo)
    [NSTimer scheduledTimerWithTimeInterval:PERIOD
                                     target:self
                                   selector:@selector(animateAllImages:)
                                   userInfo:nil
                                    repeats:NO];
  else if (imagesToDisplay) {
    /* Setup a new timer after which we display the rest of images */
    tickNo = 1;
    [NSTimer scheduledTimerWithTimeInterval:1
                                     target:self
                                   selector:@selector(animateAllImages:)
                                   userInfo:nil
                                    repeats:NO];
  }
}

@end
