package com.videonext.mplayer.internal;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.channels.FileChannel;
import java.util.Enumeration;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;

/**
 * Purpose: just avoid to load JNI dll's in different "classloaders"
 */
public class NativeHelper
{
	public static String getPlayerVersion() {
		Enumeration<URL> resEnum;
		try {
			resEnum = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
			while (resEnum.hasMoreElements()) {
				try {
					URL url = (URL)resEnum.nextElement();
					InputStream is = url.openStream();
					if (is != null) {
						Manifest manifest = new Manifest(is);
						Attributes mainAttribs = manifest.getMainAttributes();
						String version = mainAttribs.getValue("Bundle-Version");
						if(version != null) {
							return version;
						}
					}
				}
				catch (Exception e) {
					// Silently ignore wrong manifests on classpath?
				}
			}
		} catch (IOException e1) {
			// Silently ignore wrong manifests on classpath?
		}
		return null; 
	}

	public static void copyFile(File in, File out) throws Exception
	{
		FileChannel sourceChannel = null;
		FileChannel destinationChannel = null;
		try {
			sourceChannel = new FileInputStream(in).getChannel();
			destinationChannel = new FileOutputStream(out).getChannel();
			sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);
		}
		finally
		{
			if (sourceChannel != null)
				sourceChannel.close();
			
			if (destinationChannel != null)
				destinationChannel.close();
		}
	}

	private static long getPlayerLibSize(String libName) {
		Enumeration<URL> resEnum;
		try {
			resEnum = Thread.currentThread().getContextClassLoader().getResources(libName);
			while (resEnum.hasMoreElements()) {
				URLConnection conn = resEnum.nextElement().openConnection();
				return conn.getContentLength();
			}
		} catch (IOException e1) {
			// Silently ignore wrong manifests on classpath?
		}
		return 0; 
	}
	
	/**
	 * Puts library to temp dir and loads to memory
	 */
	 public static void loadFromJar(String version, String name) throws Exception 
	 {
		 String outFileName = System.getProperty("java.io.tmpdir") + File.separator + name + "." + version;

		 System.out.println("loadFromJar: " + outFileName);

		 // Check if output file exist and has same size
		 File f = new File(outFileName);
		 if (f.length() > 0 && f.length() == getPlayerLibSize("jni-lib/" + name))
		 {
			 System.out.println("loadFromJar: skipping");
			 System.load(outFileName);
			 return;
		 }

		 InputStream in = MediaPlayer.class.getResourceAsStream("/jni-lib/" + name);
		 OutputStream out = null;

		 try
		 {
			 int readBytes;
			 byte[] buffer = new byte[65536];
			 out = new FileOutputStream(new File(outFileName));
			 while ((readBytes = in.read(buffer)) > 0) 
			 {
				 out.write(buffer, 0, readBytes);
			 }
		 }
		 catch (Exception e)
		 {
			 System.err.println("Could not copy jni library: " + e.toString());
		 }

		 in.close();
		 if (out != null)
			 out.close();
		 System.out.println("Load native library: " + outFileName);
		 System.load(outFileName);
	 }
}