package cn.net.caoyao.cpzshandset.common.bitmap.crop;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.channels.FileChannel;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Environment;
import android.util.DisplayMetrics;
import android.util.Log;

public class PhotoUtils {
	private final static String TAG = "PhotoUtils";
	private final static String bFileName = "CpzsCommonHandset";
	private final static String bImageFile = "contract";

	private static PhotoUtils instance;

	private PhotoUtils() {
	}
	public static PhotoUtils getInstance() {
		if (instance == null) {
			instance = new PhotoUtils();
		}
		return instance;
	}

	/**
	 * 一切都操作uri
	 * 
	 * @return
	 */
	public Uri createImageFile(String label) {
		// String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new
		// Date());
		String imageFileName = label;
		File storageDir = createImageFilePath();
		File image = null;
		try {
			image = createImageFile(imageFileName, ".jpg", storageDir);
		} catch (IOException e) {
			e.printStackTrace();
		}

		return Uri.fromFile(image);
	}

	/**
	 * 图片存储路径
	 * 
	 * @return
	 */
	public File createImageFilePath() {
		File storageDir = Environment.getExternalStoragePublicDirectory(bFileName + File.separator + bImageFile);
		if (!storageDir.exists()) {
			if (!storageDir.mkdirs()) {
				Log.e(TAG, "createImageFile() called with: " + "创建目录失败");
			}
		}
		return storageDir;
	}
	
	
	
	

	/**
	 * 旋转图片，使图片保持正确的方向。
	 * 
	 * @param bitmap
	 *            原始图片
	 * @param degrees
	 *            原始图片的角度
	 * @return
	 */
	public Bitmap rotateBitmap(Bitmap bitmap, int degrees) {
		if (degrees == 0 || null == bitmap) {
			return bitmap;
		}
		Matrix matrix = new Matrix();
		matrix.setRotate((float) degrees, bitmap.getWidth() / 2f, bitmap.getHeight() / 2f);
		Bitmap bmp = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
		if (null != bitmap) {
			bitmap.recycle();
		}
		return bmp;
	}
	/**
	 * 最新的
	 * 
	 * @date 2015-11-26下午5:13:53
	 * @param bitmap
	 * @param degrees
	 * @return
	 */
	public Bitmap rotate2(Bitmap bitmap, int degrees) {
		if (degrees == 0 || null == bitmap) {
			return bitmap;
		}
		Matrix matrix = new Matrix();
		matrix.setRotate(degrees, (float) bitmap.getWidth() / 2, (float) bitmap.getHeight() / 2);
		try {
			Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
			if (bitmap != rotated) {
				bitmap.recycle();
				bitmap = rotated;
			}
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
		}
		return bitmap;
	}

	/**
	 * 保存方法,压缩质量
	 */
	public Uri saveBitmap(Bitmap bm, String path) {
		if (bm == null || path == null || path.isEmpty()) {
			return null;
		}
		File f = new File(path);
		FileOutputStream out = null;

		try {
			out = new FileOutputStream(f);
			Uri uri = Uri.fromFile(f);
			bm.compress(Bitmap.CompressFormat.JPEG, 90, out);
			out.flush();
			out.close();
			return uri;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			if (bm != null && !bm.isRecycled()) {
				bm.recycle();
				bm = null;
			}
		}
		return null;
	}

	/**
	 * 保存Bitmap到sdcard
	 * 
	 * @param dir
	 * @param bm
	 * @param filename
	 * @param quantity
	 */
	public boolean saveBmpToSd(String dir, Bitmap bm, int quantity) {
		boolean ret = true;
		if (bm == null) {
			return false;
		}

		File file = new File(dir);

		OutputStream outStream = null;
		try {
			file.createNewFile();
			outStream = new FileOutputStream(file);
			bm.compress(Bitmap.CompressFormat.JPEG, quantity, outStream);
			outStream.flush();
			outStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			ret = false;
		} catch (IOException e) {
			e.printStackTrace();
			ret = false;
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
			ret = false;
		} finally {
			if (outStream != null) {
				try {
					outStream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (bm != null && !bm.isRecycled()) {
				bm.recycle();
				bm = null;
				Log.e("BitmaptoCard", "saveBmpToSd, recyle");
			}
		}

		return ret;
	}

	/**
	 * 复制文件
	 * 
	 * @date 2015-11-18下午4:47:41
	 * @param sourcePath
	 * @param targetPath
	 */
	public void nioTransferCopy(String sourcePath, String targetPath) {
		nioTransferCopy(new File(sourcePath), new File(targetPath));
	}
	/**
	 * 复制图片到指定目录
	 * 
	 * @date 2015-11-18下午4:39:39
	 * @param source
	 * @param target
	 */
	public void nioTransferCopy(File source, File target) {
		FileChannel in = null;
		FileChannel out = null;
		FileInputStream inStream = null;
		FileOutputStream outStream = null;
		try {
			inStream = new FileInputStream(source);
			outStream = new FileOutputStream(target);
			in = inStream.getChannel();
			out = outStream.getChannel();
			in.transferTo(0, in.size(), out);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (inStream != null) {
					inStream.close();
				}
				if (in != null) {
					in.close();
				}
				if (outStream != null) {
					outStream.close();
				}
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 压缩图片
	 * 
	 * @date 2015-11-30上午10:51:38
	 * @param fileUri
	 * @param isCalc
	 *            是否计算
	 * @return 压缩路径
	 */
	public File scal(Uri fileUri, boolean isCalc) {
		String path = fileUri.getPath();
		File outputFile = new File(path);
		long fileSize = outputFile.length();
		Log.e("AI", "文件原始大小：" + fileSize);
		final long fileMaxSize = 200 * 1024;// 设置最大尺寸
		if (fileSize >= fileMaxSize) {
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;// 设置为true,只读尺寸信息，不加载像素信息到内存
			BitmapFactory.decodeFile(path, options);
			int height = options.outHeight;
			int width = options.outWidth;
			Log.i("AI", "height:" + height + " ;width:" + width);
			double scale = 4.0;
			Log.i("AI", "isCalc:" + isCalc + " ;width < 2800:" + (width < 2800));
			if (isCalc || width < 2800) {
				scale = Math.sqrt((float) fileSize / fileMaxSize);// 缩放的大小
				Log.i("AI", "计算后的值scale:" + scale);
			}
			options.outHeight = (int) (height / scale);
			options.outWidth = (int) (width / scale);
			// 缩放的比例，缩放是很难按准备的比例进行缩放的，其值表明缩放的倍数，SDK中建议其值是2的指数值,值越大会导致图片不清晰
			options.inSampleSize = (int) (scale + 0.5);// 设置缩放比例
			options.inJustDecodeBounds = false;// 设置读取全部

			Log.i("AI", "inSampleSize:" + options.inSampleSize + " ;outHeight:" + options.outHeight + " ;outWidth:"
					+ options.outWidth);

			Bitmap bitmap = BitmapFactory.decodeFile(path, options);

			outputFile = new File(path);
			FileOutputStream fos = null;
			try {
				fos = new FileOutputStream(outputFile);
				int quality = 70;
				// do {
				bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fos);
				// quality = quality - 10;
				Log.d("AI", "压缩----> " + outputFile.length());
				// } while (outputFile.length() > fileMaxSize);

				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			Log.d("AI", "sss ok " + outputFile.length());
			if (!bitmap.isRecycled()) {
				bitmap.recycle();
			}
			// else {
			// File tempFile = outputFile;
			// outputFile = new File(PhotoUtil.createImageFile().getPath());
			// PhotoUtil.copyFileUsingFileChannels(tempFile, outputFile);
			// }
		}
		return outputFile;

	}
	// public File scal(Uri fileUri) {
	// String path = fileUri.getPath();
	// File outputFile = new File(path);
	// long fileSize = outputFile.length();
	// final long fileMaxSize = 150 * 1024;// 设置最大尺寸
	// if (fileSize >= fileMaxSize) {
	// BitmapFactory.Options options = new BitmapFactory.Options();
	// options.inJustDecodeBounds = true;// 设置为true,只读尺寸信息，不加载像素信息到内存
	// BitmapFactory.decodeFile(path, options);
	// int height = options.outHeight;
	// int width = options.outWidth;
	// int quality = 60;
	// float maxSize = fileMaxSize; // fileMaxSize * 100 /(quality);
	// double scale = Math.sqrt((float) fileSize / maxSize);// 缩放的大小
	// // 缩放的比例，缩放是很难按准备的比例进行缩放的，其值表明缩放的倍数，SDK中建议其值是2的指数值,值越大会导致图片不清晰
	// options.inJustDecodeBounds = false;// 设置读取全部
	//
	// options.outHeight = (int) (height / scale);
	// options.outWidth = (int) (width / scale);
	// options.inSampleSize = (int) (scale);// 设置缩放比例
	// Bitmap bitmap = BitmapFactory.decodeFile(path, options);
	// FileOutputStream fos = null;
	// try {
	// fos = new FileOutputStream(outputFile);
	// bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fos);
	//
	//
	//
	//
	// fos.flush();
	// fos.close();
	// } catch (IOException e) {
	// e.printStackTrace();
	// } finally {
	// if (bitmap != null && !bitmap.isRecycled()) {
	// bitmap.recycle();
	// }
	// }
	// }
	// return outputFile;
	// }
	public void compress(String srcPath, Activity mActivity) {
		DisplayMetrics dm = new DisplayMetrics();
		mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm);

		float hh = dm.heightPixels;
		float ww = dm.widthPixels;
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, opts);
		opts.inJustDecodeBounds = false;
		int w = opts.outWidth;
		int h = opts.outHeight;
		int size = 0;
		if (w <= ww && h <= hh) {
			size = 1;
		} else {
			double scale = w >= h ? w / ww : h / hh;
			double log = Math.log(scale) / Math.log(2);
			double logCeil = Math.ceil(log);
			size = (int) Math.pow(2, logCeil);
		}
		opts.inSampleSize = size;
		bitmap = BitmapFactory.decodeFile(srcPath, opts);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		int quality = 80;
		bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
		Log.e("AI", "baos Length" + baos.toByteArray().length);
		while (baos.toByteArray().length > 45 * 1024) {
			baos.reset();
			bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
			quality -= 10;
			Log.e("AI", "baos Length" + baos.toByteArray().length);
		}
		try {
			baos.writeTo(new FileOutputStream(srcPath));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				baos.flush();
				baos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	public boolean compressImage(File file) {
		String path = file.getPath();
		Bitmap bitmap = BitmapFactory.decodeFile(path);
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片，此时把options.inJustDecodeBounds设为true
		newOpts.inJustDecodeBounds = true;
		bitmap = BitmapFactory.decodeFile(path, newOpts);
		newOpts.inJustDecodeBounds = false;
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		// 设置分辨率
		float hh = 800f;
		float ww = 480f;
		// 缩放比。由于是固定的比例缩放，只用高或者宽其中一个数据进行计算即可
		int be = 1;
		if (w > h && w > ww) {// 如果宽度大的话根据宽度固定大小缩放
			be = (int) (newOpts.outWidth / ww);
		} else if (w < h && h > hh) {// 如果宽度大的话根据宽度固定大小缩放
			be = (int) (newOpts.outHeight / hh);
		}
		if (be <= 0) {
			be = 1;
		}
		newOpts.inSampleSize = be;// 设置缩放比例
		// 重新读入图片，注意此时已经把newOpts.inJustDecodeBounds = false
		bitmap = BitmapFactory.decodeFile(path, newOpts);
		try {
			return compressImage2(bitmap);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
	}

	public boolean compressImage2(Bitmap bitmap) throws Exception {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
			int options = 100;
			int size = baos.toByteArray().length / 1024;
			while (size > 40 && options > 0) {
				baos.reset();// 重置baos即清空baos
				options -= 10;// 每次都减少10
				// 这里压缩options%，把压缩后的数据存放到baos中
				bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);
				size = baos.toByteArray().length / 1024;
			}
			// 把压缩后的数据baos存放到ByteArrayInputStream中
			ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());
			// 把ByteArrayInputStream数据生成图片
			bitmap = BitmapFactory.decodeStream(isBm, null, null);
			if (size > 40) {
				return true;
			} else {
				return false;
			}

		} catch (Exception e) {
			throw e;
		}

	}
	/**
	 * 
	 * @date 2015-11-19上午11:11:38
	 * @param prefix
	 *            前缀
	 * @param suffix
	 *            后缀
	 * @param directory
	 *            路径
	 * @return
	 * @throws IOException
	 */
	private File createImageFile(String prefix, String suffix, File directory) throws IOException {
		if (prefix.length() < 3) {
			throw new IllegalArgumentException("prefix must be at least 3 characters");
		}
		if (suffix == null) {
			suffix = ".tmp";
		}
		File tmpDirFile = directory;
		if (tmpDirFile == null) {
			String tmpDir = System.getProperty("java.io.tmpdir", ".");
			tmpDirFile = new File(tmpDir);
		}
		File result = new File(tmpDirFile, prefix + suffix);
		// do {
		// result = new File(tmpDirFile, prefix + suffix);
		// Log.e("AI", "!result.createNewFile()--->"+(!result.createNewFile()));
		// } while (!result.createNewFile());
		return result;
	}

	/**
	 * 删除单个文件
	 * 
	 * @param sPath
	 *            被删除文件的文件名
	 * @return 单个文件删除成功返回true，否则返回false
	 */
	public boolean deleteFile(String sPath) {
		boolean flag = false;
		File file = new File(sPath);
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists()) {
			file.delete();
			flag = true;
		}
		return flag;
	}

	// 删除文件和目录
	public void clearFiles() {
		File file = createImageFilePath();
		if (file.exists()) {
			deleteFile(file);
		}
	}
	private void deleteFile(File file) {
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			for (int i = 0; i < files.length; i++) {
				deleteFile(files[i]);
			}
		}
		file.delete();
	}
}
