//
//  NavigationControllerWithRotationControl : 画面回転制御を可能にしたNavigationControllerWithRotationControl
//   iOS6以降では個別のUIViewControllerが画面回転制御を行うようになり、またUINavigationControllerがある場合はそれに制御が委ねられるが、
//	 UINavigationControllerでは制御が出来ないので、これを使う。
//

#import "NavigationControllerWithRotationControl.h"


@implementation NavigationControllerWithRotationControl

#pragma mark -初期化

/// @brief 初期化
-(id)initWithRootViewController:(UIViewController *)rootViewController
{
	printSelf();
	self = [super initWithRootViewController:rootViewController];
    if (self) {
        // デフォルトは全方向の回転有効
		_orientationMask=UIInterfaceOrientationMaskAll;
		_frotationEnable=YES;
    }
    return self;
}

#pragma mark -回転制御

/// @brief 有効な回転方向を返す
/// @discussion このnaviの下に来るUIViewController内にある同名メソッドを呼び出す<br>
/// もしくは、それが存在しない時は.orientationMaskの設定値を返す<br>
/// UINavigationControllerまたはこれの配下にあるUIViewControllerでは、その中の同名メソッドではなく、これを呼び出す
/// @return UIInterfaceOrientationMask値
- (NSUInteger)supportedInterfaceOrientations
{
	printSelf();
	NSInteger cnt=[self.childViewControllers count];
	UIViewController *vc=self.childViewControllers[cnt-1]; // 最後に積まれているのが対象
	nslog(@"vc=%@",vc);
	// supportedInterfaceOrientationsはUIViewControllerの標準メソッド(optional)
	if ([vc respondsToSelector:@selector(supportedInterfaceOrientations)]) {
		_orientationMask=[vc supportedInterfaceOrientations];
	}
	return _orientationMask;
}

/// @brief 回転可能かどうかを返す
/// @discussion このnaviの下に来るUIViewController内にある同名メソッドを呼び出す<br>
/// もしくは、それが存在しない時は.frotationEnableの設定値を返す<br>
/// UINavigationControllerまたはこれの配下にあるUIViewControllerでは、その中の同名メソッドではなく、これを呼び出す
/// @return YES=回転可能 , NO=回転不可
- (BOOL)shouldAutorotate
{
	printSelf();
	NSInteger cnt=[self.childViewControllers count];
	UIViewController *vc=self.childViewControllers[cnt-1]; // 最後に積まれているのが対象
	nslog(@"vc=%@",vc);
	// shouldAutorotateはUIViewControllerの標準メソッド(optional)
	if ([vc respondsToSelector:@selector(shouldAutorotate)]) {
		_frotationEnable=[vc shouldAutorotate];
	}
	return _frotationEnable;
}

/// @brief 回転前処理
/// @discussion このnaviの下に来るUIViewController内にあるwillAnimateRotationToInterfaceOrientationForNavi:を呼び出す<br>
/// このnaviの下に来るUIViewController内に同名メソッドがある場合、これが呼び出された後に呼び出される。<br>
/// しかし、そのタイミングが遅いため、画面回転処理後に呼び出されてしまうので、will=回転前としての意味を成さない。<br>
/// ここは確実に回転前に呼び出されるので、willAnimateRotationToInterfaceOrientationForNaviを実装することで確実に回転前処理を実装できるようになる
/// @param interfaceOrientation 新しい画面方向
/// @param duration 回転アニメーションフレームレート
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
	printSelf();
	nslog(@"interfaceOrientation=%d/duration=%f",(int)interfaceOrientation,duration);
	NSInteger cnt=[self.childViewControllers count];
	id <NavigationControllerWithRotationControlProtocol> vc=self.childViewControllers[cnt-1]; // 最後に積まれているのが対象
	nslog(@"vc=%@",vc);
	if ([vc respondsToSelector:@selector(willAnimateRotationToInterfaceOrientationForNavi:)]) {
		NSArray *arg=@[[NSNumber numberWithInt:(int)interfaceOrientation],[NSNumber numberWithDouble:duration]];
		[vc willAnimateRotationToInterfaceOrientationForNavi:arg];
	}
}

/* 本来は
– willRotateToInterfaceOrientation:duration:
– didRotateFromInterfaceOrientation:
 も用意すべきだが、今回は使ってないので省略。必要なら実装を追加すること。
 （画面回転後で良ければ各UIViewController内にdidRotateFromInterfaceOrientationを実装すればいいだけだし。）
 */

@end

#pragma mark -引数を取得するための関数群

/// @brief willAnimateRotationToInterfaceOrientationForNavi:でargからinterfaceOrientationを得る
UIInterfaceOrientation getInterfaceOrientationFromArg(NSArray *arg)
{
	return [((NSNumber *)arg[0]) integerValue];
}

/// @brief willAnimateRotationToInterfaceOrientationForNavi:でargからdurationを得る
NSTimeInterval getDurationFromArg(NSArray *arg)
{
	return [((NSNumber *)arg[1]) doubleValue];
}