/**
 * Company Name : 中贸促信息技术有限责任公司
 * Project Name:project
 * File Name:UploadFileController.java
 * Package Name:org.ccpit.base.controller
 * Date:2015年10月13日下午2:38:00
 * Copyright (c) 2015, dingwei@ccpit.org All Rights Reserved.
 *
 */

package org.ccpit.base.controller;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.ccpit.base.utils.ReadConfigUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * ClassName:UploadFileController <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2015年10月13日 下午2:38:00 <br/>
 * 
 * @author dingwei
 * @version
 * @since JDK 1.6
 * @see
 */
@Controller
@RequestMapping("base/upload")
public class UploadFileController extends BaseController {

	private static final List<String> allowedContentTypes = Arrays.asList(
			"image/jpeg", "image/png", "image/gif", "image/bmp", "image/x-png");
	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
	private SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM");
	public static final String UPLOADFILEPATH = ReadConfigUtil.getPlatformConfig("system.uploadFilePath"); // 文件上传保存路径
	public static final String DOWNLOADFILEPATH = ReadConfigUtil.getPlatformConfig("system.downloadFilePath"); // 文件下载路径

	@RequestMapping("ckupload")
	public void ckUploadFile(HttpServletRequest request,
			HttpServletResponse response) {
		// response.setHeader("X-Frame-Options", "SAMEORIGIN");
		String CKEditorFuncNum = request.getParameter("CKEditorFuncNum");
		String fileName = request.getContextPath() + uploadFile(request);
		PrintWriter out;
		String s = "<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction("
				+ CKEditorFuncNum + ", '" + fileName + "');</script>";
		try {
			out = response.getWriter();
			out.print(s);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping("/progress")
	@ResponseBody
	public Object progress(HttpServletRequest request,
			HttpServletResponse response) {
		Object obj = request.getSession().getAttribute("UPLOAD_PERCENTAGE");
		if (obj == null)
			return 100.0d;
		return obj;
	}

	@RequestMapping("/uploadFile")
	@ResponseBody
	public Object uploadFile(HttpServletRequest request,
			HttpServletResponse response) {
		Map<String, Object> result = new HashMap<String, Object>();
		String file = uploadFile(request);
		result.put("message", !StringUtils.isEmpty(file));
		result.put("fileSavePath", file);
		return result;
	}

	/**
	 * 保存上传图片实现方案：在uploadFile总目录下面按照月份创建目录，当其中某一个月的图片保存文件夹大小超过200M，再在该月目录下面创建
	 * 以当天日期命名的目录用以保存上传图片
	 */
	private String uploadFile(HttpServletRequest request) {
		// 需要返回的fileName
		String fileName = "";
		String fileName1 = "";
		String dateStr = sdf.format(new Date());
		String monthStr = sdf1.format(new Date());
		String realPath = UPLOADFILEPATH + "/uploadFile" + "/" + monthStr + "/";
		String rp = "/uploadFile/" + monthStr + "/";
		DiskFileItemFactory factory = new DiskFileItemFactory();
		// Configure a repository (to ensure a secure temp location is used)
		ServletContext servletContext = request.getSession()
				.getServletContext();
		File repository = (File) servletContext
				.getAttribute("javax.servlet.context.tempdir");
		factory.setRepository(repository);
		ServletFileUpload upload = new ServletFileUpload(factory);
		// 设置单个文件的大小
		upload.setFileSizeMax(1024 * 1024);
		// 设置总共文件的大小
		upload.setProgressListener(new UploadListener(request));
		try {
			List<FileItem> items = upload.parseRequest(request);
			for (FileItem item : items) {
				String type = item.getContentType();
				if (type == null) {
					continue;
				}
				// 文件参数
				fileName = item.getName();
				File dir = null;
				if (allowedContentTypes.contains(type)) {
					// 文件大小
					long fileSize = (item.getSize() / (1024 * 1024));
					if (fileSize < 1) {
						String str = getRandomString(15);
						fileName1 = dateStr + "_" + str + "."
								+ fileName.split("[.]")[1];
						dir = new File(realPath);
						if (dir.exists()) {
							double dirLong = getUploadFileSize(dir);
							// 图片存放文件夹大小超过200M 将重新创建新的图片存放文件夹
							if (dirLong >= 200) {
								dir = new File(realPath + "/" + dateStr);
								dir.mkdir();
								rp += dateStr + "/";
							}
						} else {
							dir.mkdirs();
						}
						File f = new File(dir, fileName1);
						if (f.exists()) {
							f.delete();
						}
						f.createNewFile();
						// 保存
						item.write(f);
						return rp + fileName1;
					}
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String getRandomString(int length) { // length表示生成字符串的长度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	// 读取上传文件目录大小
	private static double getUploadFileSize(File dir) {
		// 判断文件是否存在
		if (dir.exists()) {
			// 如果是目录则递归计算其内容的总大小
			if (dir.isDirectory()) {
				File[] files = dir.listFiles();
				double size = 0;
				for (File f : files) {
					size += getUploadFileSize(f);
				}
				return size;
			} else {
				// 如果是文件则直接返回其大小,以“兆”为单位
				double size = (double) dir.length() / 1024 / 1024;
				return size;
			}
		} else {
			System.out.println("文件或者文件夹不存在，请检查路径是否正确！");
			return 0.0;
		}
	}

	private class UploadListener implements ProgressListener {
		private HttpServletRequest request;
		private DecimalFormat df = new DecimalFormat("#00.0");

		UploadListener(HttpServletRequest request) {
			this.request = request;
		}

		@Override
		public void update(long bytesRead, long bytesTotal, int items) {
			double percent = (double) bytesRead * 100 / (double) bytesTotal;
			request.getSession().setAttribute("UPLOAD_PERCENTAGE",
					df.format(percent));
		}

	}

	@RequestMapping("/uploadImage")
	@ResponseBody
	public void uploadImage(HttpServletRequest request,
			HttpServletResponse response) {
		String CKEditorFuncNum = request.getParameter("CKEditorFuncNum");
		String fileName = request.getContextPath() + uploadFile(request);
		PrintWriter out;
		String serverIp = "http://www.expo-today.com";
		String s = "<script type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction("
				+ CKEditorFuncNum
				+ ", '"
				+ serverIp
				+ fileName
				+ "');</script>";
		try {
			out = response.getWriter();
			out.print(s);
			out.flush();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "show")
	public ResponseEntity<byte[]> show(@RequestParam("path") String path, HttpServletResponse response) {
		try {
			// IE could not read ResponseEntity
			if (StringUtils.isNotBlank(path)) {
				File imageFile = new File(this.UPLOADFILEPATH, path);
				if (imageFile.exists()) {
					response.setHeader("Pragma", "No-cache");
					response.setHeader("Cache-Control", "No-cache");
					//response.setHeader("Content-Type", MediaType.IMAGE_JPEG_VALUE);
					response.setContentLength((int) imageFile.length());
					response.setContentType("image/" + path.substring(path.lastIndexOf('.') + 1));
					FileCopyUtils.copy(FileUtils.readFileToByteArray(imageFile), response.getOutputStream());
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}
