package com.glass.cuxtomcam;

import java.io.File;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.widget.TextView;

import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;
import com.googlecode.mp4parser.authoring.tracks.AppendTrack;

class VideoMerger extends AsyncTask<Void, Integer, Void> {
	interface OnVideoListener {
		public void onVideoMerged();

		public void onVideoMergeFailed(Exception e);

	}

	private ArrayList<File> videoFiles;
	private File finalVideoFile;
	private Exception exception;
	private OnVideoListener mListener;
	private Dialog progressDialog;
	private Context context;
	private TextView tv_loadingMessage;
	private long finalVideoFileSize;
	// Whether the thread that is checking file size is running or not
	private boolean fileSizeCheckerThread;

	public VideoMerger(Context context, ArrayList<File> videoFiles,
			File finalVideoFile) {
		super();
		this.context = context;
		this.videoFiles = videoFiles;
		this.finalVideoFile = finalVideoFile;
	}

	public void setVideoMergeListener(OnVideoListener mListener) {
		this.mListener = mListener;
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		progressDialog = new Dialog(context);
		progressDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		View view = LayoutInflater.from(context).inflate(
				R.layout.layout_fullscreenprogressbar, null);
		tv_loadingMessage = (TextView) view
				.findViewById(R.id.tv_loadingMessage);
		tv_loadingMessage.setText("Merging 0%");
		progressDialog.setContentView(view);
		progressDialog.getWindow().setBackgroundDrawable(
				new ColorDrawable(android.graphics.Color.TRANSPARENT));
		progressDialog.setCanceledOnTouchOutside(false);
		progressDialog.setCancelable(false);
		progressDialog.show();
	}

	@Override
	protected void onProgressUpdate(Integer... values) {
		super.onProgressUpdate(values);
		tv_loadingMessage.setText("Merging " + values[0] + "%");
	}

	@Override
	protected Void doInBackground(Void... params) {
		List<Movie> movies = new ArrayList<Movie>();
		List<Track> videoTracks = new LinkedList<Track>();
		List<Track> audioTracks = new LinkedList<Track>();
		try {
			for (int i = 0; i < videoFiles.size(); i++) {
				movies.add(MovieCreator.build(videoFiles.get(i)
						.getAbsolutePath()));
			}
			for (Movie m : movies) {
				for (Track t : m.getTracks()) {
					if (t.getHandler().equals("soun")) {
						audioTracks.add(t);
					}
					if (t.getHandler().equals("vide")) {
						videoTracks.add(t);
					}
				}
			}

			Movie finalMovie = new Movie();

			if (audioTracks.size() > 0) {
				finalMovie.addTrack(new AppendTrack(audioTracks
						.toArray(new Track[audioTracks.size()])));
			}
			if (videoTracks.size() > 0) {
				finalMovie.addTrack(new AppendTrack(videoTracks
						.toArray(new Track[videoTracks.size()])));
			}

			Container out = new DefaultMp4Builder().build(finalMovie);

			FileChannel fc = new RandomAccessFile(finalVideoFile, "rw")
					.getChannel();
			for (int i = 0; i < out.getBoxes().size(); i++) {
				finalVideoFileSize += out.getBoxes().get(i).getSize();
			}
			Thread t = new Thread(new Runnable() {

				@Override
				public void run() {
					fileSizeCheckerThread = true;
					Log.e("VideoMerge", "Started");
					long currentFileSize = 0;
					if (finalVideoFile.exists())
						currentFileSize = finalVideoFile.length();
					while (currentFileSize < finalVideoFileSize) {
						try {
							Thread.sleep(5000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
						if (finalVideoFile.exists()) {
							currentFileSize = finalVideoFile.length();
							Log.e("VideoMerge", "Total: " + finalVideoFileSize
									+ " current: " + currentFileSize);
							int progress = (int) (currentFileSize * 100 / finalVideoFileSize);
							publishProgress(progress);
						}
						if (currentFileSize >= finalVideoFileSize)
							break;

					}
					fileSizeCheckerThread = false;
					Log.e("VideoMerge", "Ended");

				}
			});
			t.start();

			out.writeContainer(fc);
			fc.close();
			for (int i = 0; i < videoFiles.size(); i++) {
				videoFiles.get(i).delete();
			}
			publishProgress(100);
			if (fileSizeCheckerThread)
				Thread.sleep(5000);

		} catch (Exception e) {
			exception = e;
		}
		return null;
	}

	@Override
	protected void onPostExecute(Void result) {
		super.onPostExecute(result);
		progressDialog.dismiss();
		if (mListener != null) {
			if (exception != null)
				mListener.onVideoMergeFailed(exception);
			else
				mListener.onVideoMerged();
		}
	}

}