/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License") +  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openmeetings.screen.webstart;

import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.FPS;
import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.spinnerHeight;
import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.spinnerWidth;
import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.spinnerX;
import static org.apache.openmeetings.screen.webstart.gui.ScreenDimensions.spinnerY;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.impl.StdSchedulerFactory.PROP_SCHED_SKIP_UPDATE_CHECK;
import static org.slf4j.LoggerFactory.getLogger;

import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;

import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.red5.server.api.Red5;
import org.red5.server.net.rtmp.event.VideoData;
import org.red5.server.stream.message.RTMPMessage;
import org.slf4j.Logger;

class CaptureScreen extends Thread {
	private static final Logger log = getLogger(CaptureScreen.class);
	private final static String QUARTZ_GROUP_NAME = "ScreenShare";
	private final static String QUARTZ_CURSOR_TRIGGER_NAME = "CursorTrigger";
	private final static String QUARTZ_CURSOR_JOB_NAME = "CursorJob";
	private CoreScreenShare core;
	private int timeBetweenFrames;
	private volatile AtomicInteger timestamp = new AtomicInteger(0);
	private volatile AtomicBoolean sendFrameGuard = new AtomicBoolean(false);
	private long timeCaptureStarted = 0;
	private volatile boolean active = true;
	private IScreenEncoder se;
	private IScreenShare client;
	private ArrayBlockingQueue<VideoData> frames = new ArrayBlockingQueue<VideoData>(2);
	private String host = null;
	private String app = null;
	private int port = -1;
	private int streamId;
	private boolean startPublish = false;
	private Scheduler scheduler;

	public CaptureScreen(CoreScreenShare coreScreenShare, IScreenShare client, String host, String app, int port) {
		core = coreScreenShare;
		this.client = client;
		this.host = host;
		this.app = app;
		this.port = port;
		final Properties p = new Properties();
		p.put(PROP_SCHED_SKIP_UPDATE_CHECK, "true");
		p.put("org.quartz.threadPool.threadCount", "10");
		try {
			SchedulerFactory sf = new StdSchedulerFactory(p);
			scheduler = sf.getScheduler();
		} catch (SchedulerException e) {
			log.error("Unexpected error while creating scheduler", e);
		}
	}

	public void release() {
		try {
			if (scheduler != null) {
				scheduler.shutdown(true);
				scheduler = null;
			}
		} catch (Exception e) {
			log.error("Unexpected error while shutting down scheduler", e);
		}
		active = false;
		timestamp = new AtomicInteger(0);
		timeCaptureStarted = 0;
	}

	public void run() {
		try {
			while (active && !core.isReadyToRecord()) {
				Thread.sleep(60);
			}

			timeBetweenFrames = 1000 / FPS;
			se = new ScreenV1Encoder(3 * FPS); //send keyframe every 3 seconds
			timeCaptureStarted = System.currentTimeMillis();

			JobDetail encodeJob = JobBuilder.newJob(EncodeJob.class).withIdentity("EncodeJob", QUARTZ_GROUP_NAME).build();
			encodeJob.getJobDataMap().put(EncodeJob.CAPTURE_KEY, this);
			Trigger encodeTrigger = TriggerBuilder.newTrigger()
					.withIdentity("EncodeTrigger", QUARTZ_GROUP_NAME)
					.withSchedule(simpleSchedule().withIntervalInMilliseconds(timeBetweenFrames).repeatForever())
					.build();
			JobDetail sendJob = JobBuilder.newJob(SendJob.class).withIdentity("SendJob", QUARTZ_GROUP_NAME).build();
			Trigger sendTrigger = TriggerBuilder.newTrigger()
					.withIdentity("SendTrigger", QUARTZ_GROUP_NAME)
					.withSchedule(simpleSchedule().withIntervalInMilliseconds(timeBetweenFrames).repeatForever())
					.build();
			sendJob.getJobDataMap().put(SendJob.CAPTURE_KEY, this);

			scheduler.scheduleJob(encodeJob, encodeTrigger);
			scheduler.scheduleJob(sendJob, sendTrigger);
			scheduler.start();
		} catch (Exception e) {
			log.error("Error while running: ", e);
		}
	}
	
	/*
	private void pushAudio(byte[] audio, long ts) {
		if (startPublish) {
			buffer.put((byte) 6);
			buffer.put(audio);
			buffer.flip();
	
			// I can stream audio
			//packets successfully using linear PCM at 11025Hz. For those packets I
			//push one byte (0x06) which specifies the format of audio data in a
			//ByteBuffer, and then real audio data:
			RTMPMessage rtmpMsg = RTMPMessage.build(new AudioData(buffer), (int) ts);
			client.publishStreamData(streamId, rtmpMsg);
		}
	}
	*/
	
	@DisallowConcurrentExecution
	public static class EncodeJob implements Job {
		private static final String CAPTURE_KEY = "capture";
		Robot robot;
		Rectangle screen = new Rectangle(spinnerX, spinnerY, spinnerWidth, spinnerHeight);
		int[][] image = null;
		
		public EncodeJob() {
			try {
				robot = new Robot();
			} catch (AWTException e) {
				log.error("encode: Unexpected Error while creating robot", e);
			}
		}
		
		@Override
		public void execute(JobExecutionContext context) throws JobExecutionException {
			JobDataMap data = context.getJobDetail().getJobDataMap();
			CaptureScreen capture = (CaptureScreen)data.get(CAPTURE_KEY);
			
			long start = 0;
			if (log.isTraceEnabled()) {
				start = System.currentTimeMillis();
			}
			image = ScreenV1Encoder.getImage(screen, robot);
			if (log.isTraceEnabled()) {
				log.trace(String.format("encode: Image was captured in %s ms, size %sk", System.currentTimeMillis() - start, 4 * image.length * image[0].length / 1024));
				start = System.currentTimeMillis();
			}
			try {
				VideoData vData = capture.se.encode(image);
				if (log.isTraceEnabled()) {
					long now = System.currentTimeMillis();
					log.trace(String.format("encode: Image was encoded in %s ms, timestamp is %s", now - start, now - capture.timeCaptureStarted));
				}
				capture.frames.offer(vData);
				capture.se.createUnalteredFrame();
			} catch (Exception e) {
				log.error("Error while encoding: ", e);
			}
		}
	}
	
	public static class SendJob implements Job {
		private static final String CAPTURE_KEY = "capture";
		public SendJob() {}
		
		@Override
		public void execute(JobExecutionContext context) throws JobExecutionException {
			JobDataMap data = context.getJobDetail().getJobDataMap();
			CaptureScreen capture = (CaptureScreen)data.get(CAPTURE_KEY);
			capture.sendFrameGuard.set(true);
			if (log.isTraceEnabled()) {
				long real = System.currentTimeMillis() - capture.timeCaptureStarted;
				log.trace(String.format("send: Enter method, timestamp: %s, real: %s, diff: %s", capture.timestamp, real, real - capture.timestamp.get()));
			}
			VideoData f = capture.frames.poll();
			if (log.isTraceEnabled()) {
				log.trace(String.format("send: Getting %s image", f == null ? "DUMMY" : "CAPTURED"));
			}
			f = f == null ? capture.se.getUnalteredFrame() : f;
			if (f != null) {
				try {
					capture.pushVideo(f, capture.timestamp.get());
					if (log.isTraceEnabled()) {
						long real = System.currentTimeMillis() - capture.timeCaptureStarted;
						log.trace(String.format("send: Sending video %sk, timestamp: %s, real: %s, diff: %s", f.getData().capacity() / 1024, capture.timestamp, real, real - capture.timestamp.get()));
					}
					capture.timestamp.addAndGet(capture.timeBetweenFrames);
					if (log.isTraceEnabled()) {
						log.trace(String.format("send: new timestamp: %s", capture.timestamp));
					}
				} catch (IOException e) {
					log.error("Error while sending: ", e);
				}
			} else if (log.isTraceEnabled()) {
				log.trace(String.format("send: nothing to send"));
			}
			capture.sendFrameGuard.set(false);
		}
	}
	
	@DisallowConcurrentExecution
	public static class CursorJob implements Job {
		private static final String CAPTURE_KEY = "capture";
		
		public CursorJob() {}
		
		@Override
		public void execute(JobExecutionContext context) throws JobExecutionException {
			JobDataMap data = context.getJobDetail().getJobDataMap();
			CaptureScreen capture = (CaptureScreen)data.get(CAPTURE_KEY);
			if (!capture.sendFrameGuard.get()) {
				capture.core.sendCursorStatus();
			}
		}
	}
	
	private void pushVideo(VideoData data, int ts) throws IOException {
		if (startPublish) {
			if (Red5.getConnectionLocal() == null) {
				Red5.setConnectionLocal(client.getConnection());
			}
			RTMPMessage rtmpMsg = RTMPMessage.build(data, ts);
			client.publishStreamData(streamId, rtmpMsg);
		}
	}

	public String getHost() {
		return host;
	}

	public String getApp() {
		return app;
	}

	public int getPort() {
		return port;
	}

	public int getStreamId() {
		return streamId;
	}

	public void setStreamId(int streamId) {
		this.streamId = streamId;
	}

	public void setStartPublish(boolean startPublish) {
		this.startPublish = startPublish;
	}

	public void setSendCursor(boolean sendCursor) {
		try {
			if (sendCursor) {
				JobDetail cursorJob = JobBuilder.newJob(CursorJob.class).withIdentity(QUARTZ_CURSOR_JOB_NAME, QUARTZ_GROUP_NAME).build();
				Trigger cursorTrigger = TriggerBuilder.newTrigger()
						.withIdentity(QUARTZ_CURSOR_TRIGGER_NAME, QUARTZ_GROUP_NAME)
						.withSchedule(simpleSchedule().withIntervalInMilliseconds(1000 / Math.min(5, FPS)).repeatForever())
						.build();
				cursorJob.getJobDataMap().put(CursorJob.CAPTURE_KEY, this);
				scheduler.scheduleJob(cursorJob, cursorTrigger);
			} else {
				scheduler.deleteJob(JobKey.jobKey(QUARTZ_CURSOR_JOB_NAME, QUARTZ_GROUP_NAME));
			}
		} catch (SchedulerException e) {
			log.error("Unexpected Error schedule/unschedule cursor job", e);
		}
	}
}
