/** CameraVideoView.m
 
 * View that handles displaying video frames
 * For now, this view displays video correctly only when created programmatically
 */

#import "CameraVideoView.h"

@implementation CameraVideoView

@synthesize delegate=_delegate, lastImage, lastFrame, labelsContainer, videoConnection;
@synthesize waitingFirstFrame;


- (id) initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self setClearsContextBeforeDrawing:NO];
        [self setOpaque:NO];
        [self setBackgroundColor:[UIColor clearColor]];
        [self setContentMode:UIViewContentModeCenter];
        
        loadingIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake((frame.size.width - 37)/2, (frame.size.height-37)/2, 37, 37)];
        [loadingIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleGray];
        [self addSubview:loadingIndicator];
        [loadingIndicator setHidesWhenStopped:YES];
        [loadingIndicator setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin];
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, rect);
    bool isOrientationPortrait = self.bounds.size.width < self.bounds.size.height;
    float coef = (self.videoConnection.sourceSize.width / self.videoConnection.sourceSize.height);
    int width = isOrientationPortrait ? self.bounds.size.width : self.bounds.size.height * coef;
    int height = isOrientationPortrait ? self.bounds.size.width / coef : self.bounds.size.height - 32;
    int x = isOrientationPortrait ? 0 : (self.bounds.size.width - width) / 2;
    int y = isOrientationPortrait ? (self.bounds.size.height - height) / 2 : 32;
    CGRect imageRect = CGRectMake(x, y, width, height);
    if (lastImage) {
        [lastImage drawInRect:imageRect];
    }
}

#pragma mark: Helper methods

- (void) setLoadingIndicatorVisible:(BOOL) visible {
    if (visible)
        [loadingIndicator startAnimating];
    else
        [loadingIndicator stopAnimating];
}

- (void) showErrorMessage:(NSString *) errorMessage {
    if (!errorMessage) {
        if (errorMessageLabel) {
            [errorMessageLabel removeFromSuperview];
            errorMessageLabel = nil;
        }
    } else {
        if (!errorMessageLabel) {
            errorMessageLabel = [[UILabel alloc] initWithFrame:self.bounds];
            [errorMessageLabel setFont:[UIFont systemFontOfSize:14]];
            [errorMessageLabel setTextAlignment:NSTextAlignmentCenter];
            [errorMessageLabel setNumberOfLines:0];
            [errorMessageLabel setOpaque:NO];
            [errorMessageLabel setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight];
            [self addSubview:errorMessageLabel];
        }
        [errorMessageLabel setText:errorMessage];
        [self setLoadingIndicatorVisible:NO];
    }
}

#pragma mark: XPSDKVideoConnectionDelegate methods

- (void) videoConnection: (XPSDKDownstreamVideoConnection *) videoConnection receivedResponse: (NSArray *) headers {
    
    NSLog(@"Camera video view received connection response");
    
    waitingFirstFrame = YES;
}

- (void) videoConnection: (XPSDKDownstreamVideoConnection *) vc receivedFrame: (XPSDKVideoConnectionFrame *) frame {
    [self setLoadingIndicatorVisible:NO];
    
    lastFrame = frame;
    
    NSLog(@"Received frame with size: %@", [NSValue valueWithCGSize:frame.image.size]);
    
    if (frame.hasSizeInformation) {
        originalRect = frame.sourceRect;
        
        if (!CGSizeEqualToSize(frame.sourceSize, self.videoConnection.sourceSize)) {
            
            NSLog(@"Camera video view received NEW size: %@ image size: %@", [NSValue valueWithCGRect:originalRect], [NSValue valueWithCGSize:frame.image.size]);
            
            self.videoConnection.sourceSize = frame.sourceSize;
            [self.delegate cameraVideoViewReceivedResolutionChange:self];
        }
    }
    
    if (frame.image) {

        if (lostConnection) {
            [self showErrorMessage:nil];
            [self.delegate cameraVideoViewRestoredConnection:self];
            lostConnection = NO;
        }
        
        lastImage = frame.image;

        [self setNeedsDisplay];
        
        if (waitingFirstFrame) {
            [self.delegate cameraVideoViewReceivedFirstFrame:self];
            [self setOpaque:YES];
            waitingFirstFrame = NO;
        }
    }
    
    if (frame.hasLiveInformation) {
        if (frame.currentLiveEvents & XPSDKVideoConnectionFrameCameraConnectionLost) {
            if (!lostConnection) {
                NSLog(@"Live view camera connection lost");
                [self showErrorMessage:@"Connection lost"];
                [self.delegate cameraVideoViewLostConnection:self];
                
                lostConnection = YES;
                
                if (waitingFirstFrame) {
                    [self.delegate cameraVideoViewReceivedFirstFrame:self];
                    [self setOpaque:YES];
                    waitingFirstFrame = NO;
                }
            }
        }
    }
}

-(void)videoConnection:(XPSDKDownstreamVideoConnection *)vc receivedHeadersForFrame:(XPSDKVideoConnectionFrame *)frame {
    if (frame.hasLiveInformation) {
        if (frame.currentLiveEvents & XPSDKVideoConnectionFrameCameraConnectionLost) {
            if (!lostConnection) {
                NSLog(@"Live view camera connection lost");
                [self showErrorMessage:@"Connection lost"];
                [self.delegate cameraVideoViewLostConnection:self];
                
                lostConnection = YES;
                
                if (waitingFirstFrame) {
                    [self.delegate cameraVideoViewReceivedFirstFrame:self];
                    [self setOpaque:YES];
                    waitingFirstFrame = NO;
                }
            }
        }
    }
    
}

- (void) videoConnection: (XPSDKDownstreamVideoConnection *) videoConnection failedWithError:(NSError *) error {
    [self showErrorMessage:@"Connection lost"];
    [self setLoadingIndicatorVisible:NO];
    [self.delegate cameraVideoViewLostConnection:self];
}

- (void) videoConnectionFinished: (XPSDKDownstreamVideoConnection *) vc {
    lastImage = nil;
    videoConnection = nil;
    videoID = nil;
    
}

- (void) videoConnection:(XPSDKDownstreamVideoConnection *)videoConnection receivedPlaylist:(XPSDKVideoConnectionSegment *)segment {
    NSLog(@"Received playlist");
}

@end
