import React from 'react';
import PropTypes from 'prop-types';

import MediaObject from '../../../model/MediaObject';

import IDUtil from '../../../util/IDUtil';
import ComponentUtil from '../../../util/ComponentUtil';
import FlexPlayerUtil from '../../../util/FlexPlayerUtil';

import SegmentationTier from './tiers/SegmentationTier';
import AnnotationTier from './tiers/AnnotationTier';

import MediaEvents from '../_MediaEvents';

import { ResourceViewerContext } from '../ResourceViewerContext';

//TODO reimplement previous/next selection
export default class TierView extends React.Component {
    static contextType = ResourceViewerContext;

    constructor(props) {
        super(props);
        this.segmentationRef = React.createRef();
        this.segmentIndex = -1;
        this.relativePosition = 0;
    }

    componentDidMount() {
        this.context.mediaEvents.bind(MediaEvents.PLAYER_POS_RAW, this.onPlayerSeek);
        document.addEventListener('keydown', this.onKeyPressed);
    }

    componentWillUnmount() {
        this.context.mediaEvents.unbind(MediaEvents.PLAYER_POS_RAW, this.onPlayerSeek);
        document.removeEventListener('keydown', this.onKeyPressed);
    }

    onKeyPressed = e => {
        switch(e.keyCode) {
            case 68: //d
                e.shiftKey ?
                    ComponentUtil.checkFocusAndExec( //shift+d
                        () => {
                            this.context.annotationClient.delete(this.context.annotationClient.activeAnnotation)
                        }
                    ) :
                    () => {}; //do nothing

            case 73: //i
                e.shiftKey ?
                    ComponentUtil.checkFocusAndExec(this.playStart) : //shift+i
                    ComponentUtil.checkFocusAndExec( //i
                        this.context.annotationClient.setStart.bind(this, this.relativePosition)
                    );
                break;
            case 79: //o
                e.shiftKey ?
                    ComponentUtil.checkFocusAndExec(this.playEnd) : //shift+o
                    ComponentUtil.checkFocusAndExec( //o
                        this.context.annotationClient.setEnd.bind(this, this.relativePosition)
                    );
                break;

            case 83: //s
                e.shiftKey ?
                    ComponentUtil.checkFocusAndExec( //shift+s
                        () => this.context.annotationClient.saveSelection()
                    ) :
                    () => {}; //do nothing
            break;

            case 78: //n
                e.shiftKey ?
                    ComponentUtil.checkFocusAndExec(
                        this.context.annotationClient.newTemporalSegment
                        ) : //shift+n
                    e.ctrlKey ?
                        ComponentUtil.checkFocusAndExec(
                            this.context.annotationClient.newTemporalSegmentFromLast.bind(this, this.onAirSeek)
                            ) : //ctrl+n
                        () => {}; //do nothing
            break;
        }
    };

    //avoid rendering everything by not using the state for the current position
    updatePosition = relativePosition => {
        this.relativePosition = relativePosition;
        this.segmentationRef.current.updatePosition(relativePosition);
    };

    onPlayerSeek = realPos => {
        this.updatePosition(
            FlexPlayerUtil.timeRelativeToOnAir(realPos, this.context.activeMediaObject)
        );
    };

    onAirSeek = time => {
        FlexPlayerUtil.seekRelativeToOnAir(
            this.props.playerAPI,
            time,
            this.context.activeMediaObject
        );
    };

    /* ------------------------------ SEGMENTATION FUNCTIONS (POSSIBLY MOVE TO STAN) ------------------------------ */

    playStart = () => {
        if(this.context.annotationClient.activeSelection) {
            this.onAirSeek(this.context.annotationClient.activeSelection.start);
        }
    };

    playEnd = () => {
        if(this.context.annotationClient.activeSelection) {
            this.onAirSeek(this.context.annotationClient.activeSelection.end);
        }
    };

    /* --------------------------------- RENDERING --------------------------- */

    renderSegmentationTier = (
        playerAPI,
        mediaObject,
        duration,
        annotationClient
    ) => {
        return (
            <SegmentationTier
                ref={this.segmentationRef}
                playerAPI={playerAPI}
                mediaObject={mediaObject}
                duration={duration}
                annotationClient={annotationClient}
                // start={activeSelection ? activeSelection.start : -1}
                // end={activeSelection ? activeSelection.end : -1}
            />
        );
    };

    renderAnnotationTier = (
        playerAPI,
        mediaObject,
        duration,
        annotationClient
    ) => {
        return (
            <AnnotationTier
                playerAPI={playerAPI}
                mediaObject={mediaObject}
                duration={duration}
                annotationClient={annotationClient}
            />
        );
    };

    render() {
        if (!this.context.annotationClient.config.editOptions.Segment) return null;
        const commonProps = [
            this.props.playerAPI,
            this.context.activeMediaObject,
            this.props.duration,
            this.context.annotationClient
        ];
        const segmentationTier = this.renderSegmentationTier(...commonProps);
        const annotationTier = this.renderAnnotationTier(...commonProps);
        return (
            <div className="row">
                <div className="col-md-12">
                    <div>
                        {segmentationTier}
                        {annotationTier}
                    </div>
                </div>
            </div>
        );
    }
}

TierView.propTypes = {
    //common properties for all tiers
    playerAPI: PropTypes.object.isRequired,
    duration: PropTypes.number.isRequired
};
