//
//  ANIMA.m
//  ANIMA
//
//  Created by admin on Sun Dec 16 2001.
//  Copyright (c) 2001 __MyCompanyName__. All rights reserved.
//

#import "ANIMA.h"

@implementation ANIMA

- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
	width_of_frame = static_cast<int>(frame.size.width);
	height_of_frame = static_cast<int>(frame.size.height);
	
	WIDTH = width_of_frame / 2;
	HEIGHT = height_of_frame / 2;
	
	bitmap1 = new unsigned char[WIDTH * 3 * HEIGHT];
	bitmap2 = new unsigned char[WIDTH * 3 * HEIGHT];
	bitmap_disp = new unsigned char[static_cast<int>(frame.size.width * 3 * frame.size.height)];
	
	frame_of_bitmap_disp = frame;
	
    
    [self setupMatrix];
    
    srand(time(NULL));
    return [super initWithFrame:frame isPreview:isPreview];
}

- (void)setupMatrix
{
    char *matrixData;
    
	matrixes = new vector<char*>();
	
	const int center_x = WIDTH / 2;
	const int center_y = HEIGHT / 2;
	
	matrixData = new char[WIDTH*HEIGHT*2];
    for (int y = 0;y < HEIGHT;y++)
    {
		for (int x = 0;x < WIDTH;x++)
		{
			matrixData[y*WIDTH*2 + x*2    ] = 0; // x
			matrixData[y*WIDTH*2 + x*2 + 1] = 5; // y
		}
    }
	matrixes->push_back(matrixData);
    
	matrixData = new char[WIDTH*HEIGHT*2];
    for (int y = 0;y < HEIGHT;y++)
    {
		for (int x = 0;x < WIDTH;x++)
		{
			matrixData[y*WIDTH*2 + x*2    ] = (x > WIDTH/2 ? 2 : -2); // x
			matrixData[y*WIDTH*2 + x*2 + 1] = (y > HEIGHT/2 ? 5 : -5); // y
		}
    }
	matrixes->push_back(matrixData);
    
	matrixData = new char[WIDTH*HEIGHT*2];
    for (int y = 0;y < HEIGHT;y++)
    {
		for (int x = 0;x < WIDTH;x++)
		{
			matrixData[y*WIDTH*2 + x*2    ] = (y > HEIGHT/2 ? (x < WIDTH/2 ? 5 : 0) : (x < WIDTH/2 ? 0 : -5)); // x
			matrixData[y*WIDTH*2 + x*2 + 1] = (y > HEIGHT/2 ? (x < WIDTH/2 ? 0 : -5) : (x < WIDTH/2 ? 5 : 0)); // y
		}
    }
	matrixes->push_back(matrixData);
	
	matrixData = new char[WIDTH*HEIGHT*2];
	for (int y = 0;y < HEIGHT;y++)
	{
		for (int x = 0;x < WIDTH;x++)
		{
			// 原点からの距離
			double delta_x = x - center_x;
			//double delta_y = (y - center_y) * -1;
			
			// 原点からの角度
			double rad = acos(delta_x / center_x); // acosは-1.0から+1.0までの値を取る。
			//if (delta_y < 0) rad *= -1;
			
			matrixData[y*WIDTH*2 + x*2    ] = static_cast<char>(cos(rad) * 4.0);
			matrixData[y*WIDTH*2 + x*2 + 1] = static_cast<char>(sin(rad) * 4.0 * -1);
		}
	}
	matrixes->push_back(matrixData);
	
	matrixData = new char[WIDTH*HEIGHT*2];
	for (int y = 0;y < HEIGHT;y++)
	{
		for (int x = 0;x < WIDTH;x++)
		{
			// 原点からの距離
			double delta_x = x - center_x;
			double delta_y = y - center_y;
			
			// 原点からの角度
			double rad = asin(delta_x / (WIDTH / 2.0));
			if (delta_y < 0) rad *= -1;
			
			matrixData[y*WIDTH*2 + x*2    ] = static_cast<char>(sin(rad) * 4.0);
			matrixData[y*WIDTH*2 + x*2 + 1] = static_cast<char>(cos(rad) * 4.0);
		}
	}
	matrixes->push_back(matrixData);
}

/*- (void)dealloc
{
    [image1 release];
    [image2 release];
    [matrixes release];
    [self dealloc];
}*/

- (void)animateOneFrame
{
    static BOOL coin = YES;
    static long counter = 0;
    static unsigned int now_mat_frame = 0;
	const double pi = acos(-1);
    char *mat;
    
	mat = (*matrixes)[now_mat_frame];
    if (counter > 30)
    {
		now_mat_frame = (now_mat_frame >= matrixes->size()-1 ? 0 : now_mat_frame+1);
		counter = 0;
    }
    counter++;
    
    if (coin)
    {
		line(bitmap1,WIDTH*3,
				20+(rand()%20),(HEIGHT/2)-20+(rand()%40),
				WIDTH-20-(rand()%20),(HEIGHT/2)-20+(rand()%40),
				1,1,
				20,255,100);
		
		matrix(bitmap1,bitmap2,mat,WIDTH,HEIGHT);
		blur(bitmap2,WIDTH,HEIGHT);
		
		rotate(bitmap2,bitmap1,WIDTH,HEIGHT,WIDTH/2,HEIGHT/2,(double)10 / (double)180 * pi);
		
		//enlarge(bitmap2,bitmap_disp,WIDTH,HEIGHT,2,2);
		enlarge(bitmap1,bitmap_disp,WIDTH,HEIGHT,2,2);
		NSDrawBitmap(frame_of_bitmap_disp,width_of_frame,height_of_frame,8,3,24,width_of_frame * 3,NO,NO,NSCalibratedRGBColorSpace,&bitmap_disp);
    }
    else
    {
		//matrix(bitmap2,bitmap1,mat,WIDTH,HEIGHT);
		matrix(bitmap1,bitmap2,mat,WIDTH,HEIGHT);
		
		rotate(bitmap2,bitmap1,WIDTH,HEIGHT,WIDTH/2,HEIGHT/2,(double)10 / (double)180 * pi);
		
		enlarge(bitmap1,bitmap_disp,WIDTH,HEIGHT,2,2);
		NSDrawBitmap(frame_of_bitmap_disp,width_of_frame,height_of_frame,8,3,24,width_of_frame * 3,NO,NO,NSCalibratedRGBColorSpace,&bitmap_disp);
    }
    coin = !coin;
}

@end
