/*
 * libjingle
 * Copyright 2013, Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

#import "RTCEnumConverter.h"
#import "RTCMediaStreamTrack+Internal.h"

namespace webrtc {

class RTCMediaStreamTrackObserver : public ObserverInterface {
 public:
  RTCMediaStreamTrackObserver(RTCMediaStreamTrack* track) { _track = track; }

  virtual void OnChanged() OVERRIDE {
    [_track.delegate mediaStreamTrackDidChange:_track];
  }

 private:
  __weak RTCMediaStreamTrack* _track;
};
}

@implementation RTCMediaStreamTrack {
  rtc::scoped_refptr<webrtc::MediaStreamTrackInterface> _mediaTrack;
  rtc::scoped_ptr<webrtc::RTCMediaStreamTrackObserver> _observer;
}

@synthesize label;

- (BOOL)isEqual:(id)other {
  // Equality is purely based on the label just like the C++ implementation.
  if (self == other)
    return YES;
  if (![other isKindOfClass:[self class]] ||
      ![self isKindOfClass:[other class]]) {
    return NO;
  }
  RTCMediaStreamTrack* otherMediaStream = (RTCMediaStreamTrack*)other;
  return [self.label isEqual:otherMediaStream.label];
}

- (NSUInteger)hash {
  return [self.label hash];
}

- (NSString*)kind {
  return @(self.mediaTrack->kind().c_str());
}

- (NSString*)label {
  return @(self.mediaTrack->id().c_str());
}

- (BOOL)isEnabled {
  return self.mediaTrack->enabled();
}

- (BOOL)setEnabled:(BOOL)enabled {
  return self.mediaTrack->set_enabled(enabled);
}

- (RTCTrackState)state {
  return [RTCEnumConverter convertTrackStateToObjC:self.mediaTrack->state()];
}

- (BOOL)setState:(RTCTrackState)state {
  return self.mediaTrack->set_state(
      [RTCEnumConverter convertTrackStateToNative:state]);
}

@end

@implementation RTCMediaStreamTrack (Internal)

- (id)initWithMediaTrack:
          (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)
      mediaTrack {
  if (!mediaTrack) {
    NSAssert(NO, @"nil arguments not allowed");
    self = nil;
    return nil;
  }
  if (self = [super init]) {
    _mediaTrack = mediaTrack;
    label = @(mediaTrack->id().c_str());
    _observer.reset(new webrtc::RTCMediaStreamTrackObserver(self));
    _mediaTrack->RegisterObserver(_observer.get());
  }
  return self;
}

- (void)dealloc {
  _mediaTrack->UnregisterObserver(_observer.get());
}

- (rtc::scoped_refptr<webrtc::MediaStreamTrackInterface>)mediaTrack {
  return _mediaTrack;
}

@end
