
#import "MediaPlayer.h"
#import "VnPlayer.h"
#import "MediaStreamHandler.h"

#import "React/RCTConvert.h"
#import "React/RCTBridgeModule.h"
#import "React/RCTEventDispatcher.h"
#import "React/UIView+React.h"

@implementation VnPlayer

@synthesize imageView;

using namespace videonext;
using namespace videonext::media;
using namespace videonext::media::iphone;

- (BOOL) isMultipleTouchEnabled {return YES;}

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
{
    if ((self = [super init])) {
        self.eventDispatcher = eventDispatcher;
        
        /* [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationWillResignActive:)
                                                     name:UIApplicationWillResignActiveNotification
                                                   object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(applicationWillEnterForeground:)
                                                     name:UIApplicationWillEnterForegroundNotification
                                                   object:nil];
        */
        
        self.backgroundColor = [UIColor whiteColor];
        // // Provide support for autorotation and resizing
        // self.autoresizesSubviews = YES;
        // self.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
        
        [self setUserInteractionEnabled:YES];
        
        updateImages = NO;
        outputHeight = 0;
        outputWidth  = 0;
        stopped = YES;
    }
  
    return self;
}

-(void)initImageViewWith:(CGRect)frame
{
    imageView=[[UIImageView alloc] initWithFrame:frame];
    imageView.backgroundColor = [UIColor lightGrayColor];
    [imageView setContentMode:UIViewContentModeScaleAspectFill];
    [self addSubview:imageView];
    
    CGRect frm = self.frame;
    frm.size.height = frame.size.height;
    frm.size.width = frame.size.width;
    
    fprintf(stderr, "initImageViewWith---------------------width=%f,height=%f\n",frm.size.width, frm.size.height);
    self.frame = frm;
}

- (void) start
{
    @synchronized (self)
    {
        if (player) {
            fprintf(stderr, "Ignore play command becase it's playing already\n");
            return;
        }
        player = new MediaPlayer(uri, self);
        player->open();
        updateImages = YES;
        stopped = NO;
    }
}

-(void) stop
{
    @synchronized (self)
    {
        if (stopped || !player)
            return;
        
        if (player)
        {
            player->teardown();
            delete player;
            player = 0;
        }
        updateImages = NO;
        stopped = YES;
    
        if (colorspaceRef) {
            CGColorSpaceRelease(colorspaceRef);
            colorspaceRef = 0;
        }
        if (dataProviderRef) {
            CGDataProviderRelease(dataProviderRef);
            dataProviderRef = 0;
        }
    }
}

-(void) newStream:(id)cbParams
{
    @synchronized (self)
    {
        CallBackCommonParams *params = (CallBackCommonParams*)cbParams;
        self.onNewStream(@{@"type":params.stream_info->type ? @"VIDEO" : @"AUDIO",
                           @"target": self.reactTag});
    }
}


- (void) stateChanged:(id)cbParams
{
	@synchronized (self)
	{
		CallBackCommonParams *params = (CallBackCommonParams*)cbParams;
	
		if (params.status == 0 || params.state == 0) return;
	
        NSString *stateStr = [NSString stringWithUTF8String:vn_player_state_to_str(*params.state)];
        
        switch (*params.state)
        {
            case ::STOPPED:
            {
                std::string errorString(params.status->error_str?params.status->error_str:"");
                if ((params.status->error_code != 0 || params.status->error_str != 0))
                {
                    fprintf(stderr, "Stopped: %s\n", params.status->error_str);
                    if (player)
                    {
                        if (dataProviderRef)
                        {
                            CGDataProviderRelease(dataProviderRef);
                            CGColorSpaceRelease(colorspaceRef);
                            dataProviderRef = 0;
                            colorspaceRef = 0;
                        }
                        player = 0;
                    }
                }
                self.onStateChanged(@{@"state":stateStr,
                                      @"target": self.reactTag,
                                      @"error":[NSString stringWithUTF8String:errorString.c_str()]
                                      });
                break;
            }
            default:
                self.onStateChanged(@{@"state":stateStr,
                                      @"target": self.reactTag});
                break;
        }
	}
}

- (void) displayFrame:(id)cbParams
{
	@synchronized (self)
	{
		if (!updateImages) return;
		
		CallBackCommonParams *params  = (CallBackCommonParams*)cbParams;
	
		if (params.frame == 0)
		{
			fprintf(stderr, "frame==0\n");
			return;
		}
        
        if (!player)
            return;
		
		if (dataProviderRef == 0)
		{
			colorspaceRef  = CGColorSpaceCreateDeviceRGB();
			dataProviderRef = CGDataProviderCreateWithData (0, params.frame->data[0], params.frame->width * params.frame->height*4, 0);
		}
	
        // fprintf(stderr, "CGImageCreate: %dx%d (%p)\n", params.frame->width, params.frame->height, params.frame->data[0]);
		CGImageRef imageRef = CGImageCreate (
										 params.frame->width,
										 params.frame->height,
							 			 8,
										 32,
										 params.frame->width * 4,
										 colorspaceRef,
										 kCGBitmapByteOrderDefault | kCGImageAlphaNoneSkipLast,
										 //kCGBitmapByteOrder32Host | kCGImageAlphaNoneSkipFirst,
										 dataProviderRef,
										 NULL,
										 0,
										 kCGRenderingIntentDefault);
	
	
	
		UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
		CGImageRelease(imageRef);
	
		[imageView setImage:image];
     
        CGRect frm = imageView.frame;
        self.frame = frm;
        
        self.onNewFrame(@{@"width":  [NSNumber numberWithUnsignedInt:params.frame->width],
                          @"height": [NSNumber numberWithUnsignedInt:params.frame->height],
                          @"pts":    [NSNumber numberWithUnsignedLongLong:((int64_t)(params.frame->captured_time->tv_sec))*1000 + params.frame->captured_time->tv_usec/1000],
                          @"target": self.reactTag});

	}
}


#pragma mark - Properties
-(void)setSource:(NSDictionary *)source
{
    uri            = [[source objectForKey:@"uri"] cStringUsingEncoding:[NSString defaultCStringEncoding]];
    outputWidth    = [RCTConvert int:[source objectForKey:@"width"]];
    outputHeight   = [RCTConvert int:[source objectForKey:@"height"]];
    fprintf(stderr, "setSource------------------------------------------width=%i,height=%i,uri=%s\n",outputWidth,outputHeight,uri.c_str());
    
        NSArray *viewsToRemove = [self subviews];
        for (UIView *v in viewsToRemove) {
            [v removeFromSuperview];
        }

    CGRect frame = CGRectMake(0, 0, outputWidth, outputHeight);
    
    [self initImageViewWith:frame];
}

-(void)setPlay:(BOOL)value
{
    if (value)
        [self start];
    else
        [self stop];
}

-(void)setFullscreen:(BOOL)isFull
{
    CGRect screenBounds = [[UIScreen mainScreen] bounds];
    int width = (int)screenBounds.size.width;
    int height = (int)screenBounds.size.height;
    if(isFull && fullscreen==NO){
        fprintf(stderr, "---------------------------------------------setFullscreen: %d\n", isFull);
        fullscreen = YES;
        CGAffineTransform transform = CGAffineTransformMakeRotation(90 * M_PI/180.0);
        
        [imageView setTransform:transform];
        [imageView setFrame:CGRectMake(0, 0, width,height)];
        
        [self setFrame:CGRectMake(0, 0, width,height)];
        
    }else if(isFull == NO && fullscreen == YES){
        fprintf(stderr, "---------------------------------------------setFullscreen: %d\n", isFull);
        fullscreen = NO;
        CGAffineTransform transform = CGAffineTransformMakeRotation(0);
        [imageView setTransform:transform];
        [imageView setFrame:CGRectMake(0, 0, outputWidth, outputHeight)];
        [self setFrame:CGRectMake(0, 0, outputWidth, outputHeight)];
    }
  
}


#pragma mark - Lifecycle
- (void)removeFromSuperview
{
    fprintf(stderr, "------------------------------removeFromSuperview\n");
    [super removeFromSuperview];
}

- (void)dealloc {
	if (colorspaceRef)
		CGColorSpaceRelease(colorspaceRef);
	if (dataProviderRef)
		CGDataProviderRelease(dataProviderRef);
}

@end


