//
//  ReservationItem.m
//  VH7PC_Controller
//
//  Created by nya on 04/12/04.
//  Copyright 2004 __MyCompanyName__. All rights reserved.
//

#import "ReservationItem.h"
#import "ReservationController.h"


//#define RECORD_WAIT				10


@implementation ReservationItem

- (NSString *) filename {
	return [[self title] stringByAppendingString:[[self nextRecDate] descriptionWithCalendarFormat:@"_%Y%m%d_%H%M" timeZone:nil locale:nil]];
}

/*
- (void) recStart {
	[delegate_ recStart:self];
	timer_ = [NSTimer scheduledTimerWithTimeInterval:length_ + 2 * RECORD_WAIT target:self selector:@selector(recEnd) userInfo:nil repeats:NO];
}

- (void) recEnd {
	[delegate_ recEnd:self];
	timer_ = nil;
	if (week_) 
		timer_ = [NSTimer scheduledTimerWithTimeInterval:[[self nextRecDate] timeIntervalSinceNow] - RECORD_WAIT target:self selector:@selector(recStart) userInfo:nil repeats:NO];
}
*/


#pragma mark-


+ (id) itemWithDictionary:(NSDictionary *)dic {
	id res = [[[ReservationItem alloc] initWithDictionary:dic] autorelease];
	
	//NSLog(@"itemWithDictionary retaincount = %d", [res retainCount]);
	return res;
}

+ (id) item {
	return [[[ReservationItem alloc] init] autorelease];
}

- (id) initWithDictionary:(NSDictionary *)dic {
	self = [super init];
	if (!self) return nil;
	//NSLog(@"iinitWithDictionary init retaincount = %d", [self retainCount]);
	
	memset(&date_, 0x0, sizeof(ResDate));
	memset(&time_, 0x0, sizeof(ResTime));
	memset(&week_, 0x0, sizeof(ResWeek));
	
	id tmp;
	tmp = [dic objectForKey:RES_ITEM_WEEK_KEY];
	if (tmp) {
		week_ = [tmp intValue];
	}
	
	tmp = [dic objectForKey:RES_ITEM_YEAR_KEY];
	if (tmp) {
		date_.year = [tmp intValue];
	}
	tmp = [dic objectForKey:RES_ITEM_MONTH_KEY];
	if (tmp) {
		date_.month = [tmp intValue];
	}
	tmp = [dic objectForKey:RES_ITEM_DAY_KEY];
	if (tmp) {
		date_.day = [tmp intValue];
	}
	
	tmp = [dic objectForKey:RES_ITEM_HOUR_KEY];
	if (tmp) {
		time_.hour = [tmp intValue];
	}
	tmp = [dic objectForKey:RES_ITEM_MINUTE_KEY];
	if (tmp) {
		time_.minute = [tmp intValue];
	}
	tmp = [dic objectForKey:RES_ITEM_SECOND_KEY];
	if (tmp) {
		time_.second = [tmp intValue];
	}
	
	tmp = [dic objectForKey:RES_ITEM_INTERVAL_KEY];
	if (tmp) {
		length_ = [tmp longValue];
	}

	tmp = [dic objectForKey:RES_ITEM_PRESET_KEY];
	if (tmp) {
		preset_ = [tmp intValue];
	}
	
	tmp = [dic objectForKey:RES_ITEM_INPUT_KEY];
	if (tmp) {
		input_ = [tmp intValue];
	}

	//tmp = [dic objectForKey:RES_ITEM_DELEGATE_KEY];
	//if (tmp) {
	//	delegate_ = tmp;
	//}
	
	tmp = [dic objectForKey:RES_ITEM_POWEROFF_KEY];
	if (tmp) {
		autoPower_ = [tmp boolValue];
	}
	
	if (week_ == 0x00 && (![self date] || [[self date] timeIntervalSinceNow] <= 0)) {
		return nil;
	}

	tmp = [dic objectForKey:RES_ITEM_TITLE_KEY];
	if (tmp) {
		title_ = [tmp retain];
	}
	
	//timer_ = nil;
	//timer_ = [NSTimer scheduledTimerWithTimeInterval:[[self nextRecDate] timeIntervalSinceNow] - RECORD_WAIT target:self selector:@selector(recStart) userInfo:nil repeats:NO];

	//[self release];
	//NSLog(@"iinitWithDictionary retaincount = %d", [self retainCount]);
	return self;
}

- (id) init {
	self = [super init];
	if (!self) return nil;
	
	//現在時刻から1時間（テキトー）
	NSDate *date = [NSDate date];
	
	title_ = [[NSString stringWithString:@""] retain];
	date_.year = [[date descriptionWithCalendarFormat:@"%Y" timeZone:nil locale:nil] intValue];
	date_.month = [[date descriptionWithCalendarFormat:@"%m" timeZone:nil locale:nil] intValue];
	date_.day = [[date descriptionWithCalendarFormat:@"%d" timeZone:nil locale:nil] intValue];
	time_.hour = [[date descriptionWithCalendarFormat:@"%H" timeZone:nil locale:nil] intValue];
	time_.minute = [[date descriptionWithCalendarFormat:@"%M" timeZone:nil locale:nil] intValue];
	time_.second = 0;
	length_ = 0;
	preset_ = 1;
	input_ = 0;
	autoPower_ = YES;
	
	//timer_ = nil;
	
	return self;
}

- (void) dealloc {
	NSLog(@"item dealloc");

	[title_ release];
	//if (timer_) [timer_ invalidate];
	[super dealloc];
}

- (void) unregistTimer {
	//if (timer_) [timer_ invalidate];
	//timer_ = nil;
}

- (NSDictionary *) dictionary {
	return
		[NSDictionary dictionaryWithObjectsAndKeys:
			title_,									RES_ITEM_TITLE_KEY,
			[NSNumber numberWithInt:week_],			RES_ITEM_WEEK_KEY,
			[NSNumber numberWithInt:date_.year],	RES_ITEM_YEAR_KEY,
			[NSNumber numberWithInt:date_.month],	RES_ITEM_MONTH_KEY,
			[NSNumber numberWithInt:date_.day],		RES_ITEM_DAY_KEY,
			[NSNumber numberWithInt:time_.hour],	RES_ITEM_HOUR_KEY,
			[NSNumber numberWithInt:time_.minute],	RES_ITEM_MINUTE_KEY,
			[NSNumber numberWithInt:time_.second],	RES_ITEM_SECOND_KEY,
			[NSNumber numberWithInt:preset_],		RES_ITEM_PRESET_KEY,
			[NSNumber numberWithInt:input_],		RES_ITEM_INPUT_KEY,
			[NSNumber numberWithLong:length_],		RES_ITEM_INTERVAL_KEY,
			[NSNumber numberWithBool:autoPower_],	RES_ITEM_POWEROFF_KEY,
			nil
		];
}

- (NSString *)title {
	return title_;
}

- (NSDate *)date {
	/*
	char str[20];
	sprintf(str, "%04d-%02d-%02d %02d:%02d:%02d\n", date_.year, date_.month, date_.day, time_.hour, time_.minute, time_.second);

	NSString *datestr = [NSString stringWithCString:str length:19];
	NSString *tzonestr = [[NSDate date] descriptionWithCalendarFormat:@"%z" timeZone:nil locale:nil];

	NSDate	*res = [NSDate dateWithString:[NSString stringWithFormat:@"%@ %@", datestr, tzonestr]];
	return res;
	*/
	return [NSCalendarDate 
		dateWithString:[NSString stringWithFormat:@"%d/%d/%d %d:%d", date_.year, date_.month, date_.day, time_.hour, time_.minute, time_.second]
		calendarFormat:@"%Y/%m/%d %H:%M"];
}

- (NSString *)dateString {
	if (week_) {
		NSMutableString *res = [NSMutableString stringWithString:@""];
		int i;
		
		for (i = 0; i < 7; i++) {
			if ((week_ >> i) & 0x01) {
				NSString *weekstr = nil;
				switch (i) {
				case 0:
					weekstr = [[NSBundle mainBundle] localizedStringForKey:@"Sun" value:nil table:nil];
					break;
				case 1:
					weekstr = [[NSBundle mainBundle] localizedStringForKey:@"Mon" value:nil table:nil];
					break;
				case 2:
					weekstr = [[NSBundle mainBundle] localizedStringForKey:@"Tue" value:nil table:nil];
					break;
				case 3:
					weekstr = [[NSBundle mainBundle] localizedStringForKey:@"Wed" value:nil table:nil];
					break;
				case 4:
					weekstr = [[NSBundle mainBundle] localizedStringForKey:@"Thu" value:nil table:nil];
					break;
				case 5:
					weekstr = [[NSBundle mainBundle] localizedStringForKey:@"Fri" value:nil table:nil];
					break;
				case 6:
					weekstr = [[NSBundle mainBundle] localizedStringForKey:@"Sat" value:nil table:nil];
					break;
				default:
					break;
				}
				if (weekstr) {
					[res appendString:weekstr];
					//[res appendString:@" "];
				}
			}
		}
		
		[res appendString:[[NSBundle mainBundle] localizedStringForKey:@"day" value:nil table:nil]];
		return res;
	} else {
		return [[self date] descriptionWithCalendarFormat:@"%Y/%m/%d" timeZone:nil locale:nil];
	}
}

- (NSString *)timeString {
	NSDate *end = [[NSDate alloc] initWithTimeInterval:length_ sinceDate:[self nextRecDate]];
	NSString *sstr = [[self nextRecDate] descriptionWithCalendarFormat:@"%H:%M" timeZone:nil locale:nil];
	NSString *estr = [end descriptionWithCalendarFormat:@"%H:%M" timeZone:nil locale:nil];
	[end release];
	
	return [NSString stringWithFormat:@"%@ - %@", sstr, estr];
}

- (unsigned char) week {
	return week_;
}

- (unsigned long)length {
	return length_;
}

- (int) input {
	return input_;
}

- (int) preset {
	return preset_;
}

- (BOOL)autopower {
	return autoPower_;
}

static ResWeek rotateWeek(ResWeek week, int w, int direction) {			//右が正
	UInt8	tmp;
	int		i;
	
	if (direction > 0) {
		for (i = 0; i < w; i++) {
			tmp = 0x40 & (week << 6);
			week >>= 1;
			week |= tmp;
		}
	} else {
		for (i = 0; i < w; i++) {
			tmp = 0x01 & (week >> 6);
			week <<= 1;
			week |= 0x7F;
			week |= tmp;
		}
	}
	
	return week;
}

- (NSDate *) nextRecDate {
	NSDate	*resdate = nil;

	if (week_ == 0x00) {
		resdate = [self date];
	} else {
		NSCalendarDate *now = [NSCalendarDate calendarDate];
		NSCalendarDate *today = [NSCalendarDate 
			dateWithYear:[now yearOfCommonEra] 
			month:[now monthOfYear] 
			day:[now dayOfMonth] 
			hour:time_.hour
			minute:time_.minute 
			second:time_.second 
			timeZone:[now timeZone]];
		int nowWeek = [now dayOfWeek];
		int i = 0;
		ResWeek week = week_;
		
		//long nowsec = [now hourOfDay] * 60 * 60 + [now minuteOfHour] * 60 + [now secondOfMinute];
		//long sec = time_.hour * 60 * 60 + time_.minute * 60 + time_.second;

		
		if ([today timeIntervalSinceDate:now] < 0) {
			nowWeek++;
			i++;
			if (nowWeek > 6) nowWeek = 0;
		}
		
		/*
		if (nowsec > sec) {
			nowWeek++;
			i++;
		}
		*/
		
		week = rotateWeek(week, nowWeek, 1);
		while ((week & 0x01) == 0x00) {
			nowWeek++;
			i++;
			if (nowWeek > 6) nowWeek = 0;
			week = rotateWeek(week, 1, 1);
		}
		
		/*
		NSCalendarDate *res = [NSCalendarDate 
			dateWithYear:[now yearOfCommonEra] 
			month:[now monthOfYear] 
			day:[now dayOfMonth] 
			hour:time_.hour
			minute:time_.minute 
			second:0
			timeZone:nil];
		*/
		resdate = [today dateByAddingYears:0 months:0 days:i hours:0 minutes:0 seconds:0];
	}
	
	//NSLog(@"nextRecDate: %@", [resdate description]);
	return resdate;
}

- (NSDate *) prevStopDate {
	NSDate	*resdate = nil;

	if (week_ == 0x00) {
		resdate = [[[NSDate alloc] initWithTimeInterval:[self length] sinceDate:[self date]] autorelease];
	} else {
		NSCalendarDate *now = [NSCalendarDate calendarDate];
		NSCalendarDate *today = [NSCalendarDate 
			dateWithYear:[now yearOfCommonEra] 
			month:[now monthOfYear] 
			day:[now dayOfMonth] 
			hour:time_.hour
			minute:time_.minute 
			second:time_.second 
			timeZone:[now timeZone]];
		NSCalendarDate *stop = [[[NSCalendarDate alloc] initWithTimeInterval:[self length] sinceDate:today] autorelease];
		int nowWeek = [now dayOfWeek];
		int i = 0;
		ResWeek week = week_;
		
		if ([now timeIntervalSinceDate:stop] < 0) {
			nowWeek--;
			i--;
			if (nowWeek < 0) nowWeek = 6;
		}
		
		week = rotateWeek(week, nowWeek, -1);
		while ((week & 0x01) == 0x00) {
			nowWeek--;
			i--;
			if (nowWeek < 0) nowWeek = 6;
			week = rotateWeek(week, 1, -1);
		}
		
		resdate = [stop dateByAddingYears:0 months:0 days:i hours:0 minutes:0 seconds:0];
	}
	
	//NSLog(@"prevStopDate: %@", [resdate description]);
	return resdate;
}

@end
