package fishrungames.bashgid.core;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.Semaphore;

import fishrungames.bashgid.MainActivity;
import fishrungames.bashgid.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Base64;
import android.util.Log;
import android.widget.ImageView;

public class ImageManager {

	static ImageManager instance = null;
	
	private volatile Semaphore downloadingFileNameSetMutex = new Semaphore(1, true);
	private volatile HashSet<String> downloadingFileNameSet = new HashSet<String>();
	
	
	public static ImageManager getInstance()
	{
		if (instance == null)
		{
			instance = new ImageManager();
		}
		
		return instance;
	}
	
	
	HashMap<String, Integer> PredefinedImageId = new HashMap<String, Integer>();
	
	public ImageManager()
	{
		PredefinedImageId.put("R.drawable.transparent", R.drawable.transparent);
	}
	
	
	
	
	public void ApplyImageToImageView(ImageView imageView, String imageId)
	{
		//Xperimental -- Should be called only in main thread
		
		if (imageId.startsWith("R.drawable."))
		{
			Integer resourceId = PredefinedImageId.get(imageId);
			
			if (resourceId == null)
			{
				Log.e("Error: ", "Image not added to PredefinedImageId: " + imageId);
				
				resourceId = R.drawable.transparent;
			}
			
			imageView.setImageResource(resourceId);
		}
		else
		{
			String fileName = ImageUrlToFileName(imageId);
			
			File f = MainActivity.getInstance().getFileStreamPath(fileName);
			
			if (f.exists())
			{
				
				boolean fileIsBusy = false;
				
				
				try
				{
					downloadingFileNameSetMutex.acquire();
					try
					{					
						fileIsBusy = downloadingFileNameSet.contains(fileName);
					} finally
					{
						downloadingFileNameSetMutex.release();
					}
				} catch (InterruptedException ie)
				{
					Log.e("Error in ApplyImageToImageView", "Error in ApplyImageToImageView");
				}
				
				
				if (!fileIsBusy)
				{
									
					Bitmap bitmap = BitmapFactory.decodeFile( MainActivity.getInstance().getFileStreamPath(fileName).getAbsolutePath());
				
					imageView.setImageBitmap(bitmap);
				
				}
				
				
				
			}
			else
			{
				imageView.setImageResource(R.drawable.transparent);
			}
		}
	}

	
	public static String ImageUrlToFileName(String imageUrl)
	{
		String beforeExtension = imageUrl.substring(0, imageUrl.lastIndexOf("."));
		String extension = imageUrl.substring(imageUrl.lastIndexOf("."));
		
		return Base64.encodeToString(beforeExtension.getBytes(), Base64.DEFAULT).replace("\n", "") + extension;
	}
	
	public void DownloadImageIfNeeded(String imageUrl)
	{
		String fileName = ImageUrlToFileName(imageUrl);
		
		File f = MainActivity.getInstance().getFileStreamPath(fileName);
		
		if (f.exists())
		{
			return;
		}
		
		boolean fileIsBusy = false;
		
		
		try
		{
			downloadingFileNameSetMutex.acquire();
			try
			{			
				if (downloadingFileNameSet.contains(fileIsBusy))
				{
					fileIsBusy = true;
				}
				else
				{
					downloadingFileNameSet.add(fileName);
				}
			} finally
			{
				downloadingFileNameSetMutex.release();
			}
		} catch (InterruptedException ie)
		{
			Log.e("Error in DownloadImageIfNeeded", "Error in DownloadImageIfNeeded");
		}
		
		if (!fileIsBusy)
		{
		
			try {
		        InputStream is = (InputStream) new URL(imageUrl).getContent();
		        
		        FileOutputStream out = null;
		        
		        out = MainActivity.getInstance().openFileOutput(fileName, Context.MODE_PRIVATE);
		        
		        byte [] buf = new byte[1024];
		         
		        int numRead;
		        
		        while ( (numRead = is.read(buf) ) >= 0) {
		        	out.write(buf, 0, numRead);
		        }
		        
		        out.close();    
		   
	
			} catch (Exception e) {
		        e.printStackTrace();
		    }
			
			
			try
			{
				downloadingFileNameSetMutex.acquire();
				try
				{			

					downloadingFileNameSet.remove(fileName);

				} finally
				{
					downloadingFileNameSetMutex.release();
				}
			} catch (InterruptedException ie)
			{
				Log.e("Error in DownloadImageIfNeeded", "Error in DownloadImageIfNeeded");
			}
		
		
		}
	}
	
	public String GetImageLocalUrl(String imageUrl)
	{
		return "file://" + MainActivity.getInstance().getFilesDir().getAbsolutePath() + "/" + ImageUrlToFileName(imageUrl);
	}
	
	
	
}
