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

import IDUtil from '../../../../util/IDUtil';
import { ResourceViewerContext } from '../../ResourceViewerContext';
import { MSAnnotationUtil, AnnotationEvents } from '../../AnnotationClient';

//TODO this component should use the annotationClient as only prop
export default class AnnotationTier extends React.PureComponent {

	static contextType = ResourceViewerContext; //TODO maybe instead pass the annotationClient as prop...

	constructor(props) {
		super(props);
		this.hoverPos = -1;
		this.repainting = false;
	}

	/* ----------------------- FOR RENDERING THE CANVAS PROPERLY -----------------------*/

	componentDidMount() {
		//make sure the canvas is resized properly whenever the window is resized
	    window.addEventListener('resize', this.updateCanvasDimensions);

	    //add a mouse move listener to the canvas, so it's possible to highlight annotations hovered over
	    const c = document.getElementById("an_timebar_canvas__" + this.props.mediaObject.id);
	    c.addEventListener('mousemove', this.highlightAnnotation);

	    //listen to changes in annotations & active annotations
	    this.props.annotationClient.events.bind(AnnotationEvents.ON_SAVE, this.onUpdate);
        this.props.annotationClient.events.bind(AnnotationEvents.ON_DELETE, this.onUpdate);
        this.props.annotationClient.events.bind(AnnotationEvents.ON_SET_ANNOTATION, this.onUpdate);
        this.props.annotationClient.events.bind(AnnotationEvents.ON_CHANGE_TARGET, this.onUpdate);

        this.updateCanvasDimensions();
	}

	componentWillUnmount() {
		window.removeEventListener('resize', this.updateCanvasDimensions);
		const c = document.getElementById("an_timebar_canvas__" + this.props.mediaObject.id);
	    c.removeEventListener('mousemove', this.highlightAnnotation);
	    this.props.annotationClient.events.unbind(AnnotationEvents.ON_SAVE, this.onUpdate);
        this.props.annotationClient.events.unbind(AnnotationEvents.ON_DELETE, this.onUpdate);
        this.props.annotationClient.events.unbind(AnnotationEvents.ON_SET_ANNOTATION, this.onUpdate);
        this.props.annotationClient.events.unbind(AnnotationEvents.ON_CHANGE_TARGET, this.onUpdate);
	}

	updateCanvasDimensions = () => {
		const c = document.getElementById('an_timebar_canvas__' + this.props.mediaObject.id);
		const container = document.getElementById('an_timebar__' + this.props.mediaObject.id);
		c.width = container.offsetWidth;
		c.height = container.offsetHeight;
	};

	onUpdate = data => {
		this.repaint();
	};

	onDeleteAnnotation = annotation => {
		this.repaint();
	};

	/* ----------------------- FOR ACCESSING THE ANNOTATIONS -----------------------*/

	//TODO update the active annotation after pressing play
	activateAnnotation = e => {
		const activePos = parseFloat(this.hoverPos);
		const currentAnnotation = this.props.annotationClient.annotations.filter((a, index)=> {
			if(a.target.selector && a.target.selector.refinedBy) {
				if(a.target.selector.refinedBy.start < activePos && a.target.selector.refinedBy.end > activePos) {
					return true;
				}
			}
		})
		if(currentAnnotation.length == 1) {
			this.context.annotationClient.play(currentAnnotation[0]);
		}
	};

	editAnnotation = () => {
		const currentAnnotation = this.props.annotationClient.annotations.filter((a, index)=> {
			if(a.target.selector && a.target.selector.refinedBy) {
				if(a.target.selector.refinedBy.start < this.hoverPos && a.target.selector.refinedBy.end > this.hoverPos) {
					return true;
				}
			}
		})
		if(currentAnnotation.length == 1) {
			this.context.annotationClient.edit(currentAnnotation[0]);
		}
	};

	highlightAnnotation = e => {
		const c = document.getElementById("an_timebar_canvas__" + this.props.mediaObject.id);
		const mousePos = this.getMousePos(c, e);
		const dur = this.props.duration;
		this.hoverPos = dur / 100 * (mousePos.x / (c.width / 100));
		if(this.props.playerAPI.isPaused(paused => {
			if(paused) {
				this.repaint();
			}
		}));
	}

	/* ----------------------- FOR DRAWING THE CANVAS ----------------------- */

	repaint() {
		if(this.repainting) {
			return;
		}
		this.repainting = true;
		const c = document.getElementById("an_timebar_canvas__" + this.props.mediaObject.id);
		const ctx = c.getContext("2d");
		if(c.width == 0 && c.height == 0) {
			this.updateCanvasDimensions();
		}
        ctx.clearRect (0, 0, c.width, c.height);
        if(this.props.annotationClient.annotations) {
	        this.props.annotationClient.annotations.forEach((a, index) => {
	        	if(a.target) {
	        		const frag = MSAnnotationUtil.extractSelectionFromTarget(a.target);
		        	if(frag && frag.type == 'temporal') {
			        	const start = c.width / 100 * (frag.start / (this.props.duration / 100));
			        	const end = c.width / 100 * (frag.end / (this.props.duration / 100));
			        	if(this.props.annotationClient.activeAnnotation && a.id == this.props.annotationClient.activeAnnotation.id) {
			        		ctx.fillStyle = "lime";
			        	} else if(this.hoverPos >= frag.start && this.hoverPos <= frag.end) {
			        		ctx.fillStyle = "#FF69B4";
			        	} else {
			        		ctx.fillStyle = "#00bfff";
			        	}
			        	ctx.fillRect(start, 0, end - start, c.height / 2);//time progressing
			        }
			    }
	        });
	    }
        this.repainting = false;
	}

	getMousePos(canvas, evt) {
	    const rect = canvas.getBoundingClientRect();
	    return {
	      x: evt.clientX - rect.left,
	      y: evt.clientY - rect.top
	    };
	}

	render() {
		return (
			<div id={'an_timebar__' + this.props.mediaObject.id} className={IDUtil.cssClassName('annotation-timeline')}>
				<canvas id={'an_timebar_canvas__' + this.props.mediaObject.id} width="300" height="50"
					onClick={this.activateAnnotation}
					onDoubleClick={this.editAnnotation}>
				</canvas>
			</div>
		)
	}

}

AnnotationTier.propTypes = {
	playerAPI : PropTypes.object.isRequired,
    mediaObject : PropTypes.object.isRequired,
    duration : PropTypes.number.isRequired,
    annotationClient : PropTypes.object.isRequired
}