//
//  YSRACBehaviorSubject.m
//  ReactiveObjC
//
//  Created by Josh Abernathy on 3/16/12.
//  Copyright (c) 2012 GitHub, Inc. All rights reserved.
//

#import "YSRACBehaviorSubject.h"
#import "YSRACDisposable.h"
#import "YSRACScheduler+Private.h"

@interface YSRACBehaviorSubject<ValueType> ()

// This property should only be used while synchronized on self.
@property (nonatomic, strong) ValueType currentValue;

@end

@implementation YSRACBehaviorSubject

#pragma mark Lifecycle

+ (instancetype)behaviorSubjectWithDefaultValue:(id)value {
	YSRACBehaviorSubject *subject = [self subject];
	subject.currentValue = value;
	return subject;
}

#pragma mark YSRACSignal

- (YSRACDisposable *)subscribe:(id<YSRACSubscriber>)subscriber {
	YSRACDisposable *subscriptionDisposable = [super subscribe:subscriber];

	YSRACDisposable *schedulingDisposable = [YSRACScheduler.subscriptionScheduler schedule:^{
		@synchronized (self) {
			[subscriber sendNext:self.currentValue];
		}
	}];
	
	return [YSRACDisposable disposableWithBlock:^{
		[subscriptionDisposable dispose];
		[schedulingDisposable dispose];
	}];
}

#pragma mark YSRACSubscriber

- (void)sendNext:(id)value {
	@synchronized (self) {
		self.currentValue = value;
		[super sendNext:value];
	}
}

@end
