package com.jcodecraeer.jcode;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Date;

import org.apache.commons.httpclient.HttpException;
import org.apache.http.client.ClientProtocolException;


import android.content.Context;
import android.os.Environment;
import android.widget.Toast;

/**
 * 应用程序异常类：用于捕获异常和提示错误信息
 * @version 1.0
 * @created 2013-11-12
 */
public class AppException extends Exception {

	private final static boolean Debug = false;//是否保存错误日志
	
	/** 定义异常类型 */
	public final static byte TYPE_NETWORK 	= 0x01;
	public final static byte TYPE_SOCKET	= 0x02;
	public final static byte TYPE_HTTP_CODE	= 0x03;
	public final static byte TYPE_HTTP_ERROR= 0x04;
	public final static byte TYPE_XML	 	= 0x05;
	public final static byte TYPE_IO	 	= 0x06;
	public final static byte TYPE_RUN	 	= 0x07;
	public final static byte TYPE_JSON      = 0x08;
	
	private byte type;
	private int code;
	private String exceptionMessage = "发生异常";
	
	private AppException(byte type, int code, Exception excp) {
		super(excp);
		this.type = type;
		this.code = code;		
		if(Debug){
			this.saveErrorLog(excp);
		}
	}
	private AppException(byte type, int code, Exception excp,String message) {
		super(excp);
		this.type = type;
		this.code = code;
		this.exceptionMessage = message;
		if(Debug){
			this.saveErrorLog(excp);
		}
	}
	public int getCode() {
		return this.code;
	}
	public int getType() {
		return this.type;
	}
	public String getExceptionMes() {
		return this.exceptionMessage;
	}
	
	/**
	 * 提示友好的错误信息
	 * @param ctx
	 */
	public void makeToast(Context ctx){
		switch(this.getType()){
		case TYPE_HTTP_CODE:
			//String err = ctx.getString(R.string.http_status_code_error, this.getCode());
			//Toast.makeText(ctx, err, Toast.LENGTH_SHORT).show();
			break;
		case TYPE_HTTP_ERROR:
			//Toast.makeText(ctx, R.string.http_exception_error, Toast.LENGTH_SHORT).show();
			break;
		case TYPE_SOCKET:
			//Toast.makeText(ctx, R.string.socket_exception_error, Toast.LENGTH_SHORT).show();
			break;
		case TYPE_NETWORK:
			//Toast.makeText(ctx, R.string.network_not_connected, Toast.LENGTH_SHORT).show();
			break;
		case TYPE_XML:
			//Toast.makeText(ctx, R.string.xml_parser_failed, Toast.LENGTH_SHORT).show();
			break;
		case TYPE_JSON:
			//Toast.makeText(ctx, R.string.json_parser_failed, Toast.LENGTH_SHORT).show();
			break;
		case TYPE_IO:
			//Toast.makeText(ctx, R.string.io_exception_error, Toast.LENGTH_SHORT).show();
			break;
		case TYPE_RUN:
			//Toast.makeText(ctx, R.string.app_run_code_error, Toast.LENGTH_SHORT).show();
			break;
		}
	}
	
	/**
	 * 保存异常日志
	 * @param excp
	 */
	public void saveErrorLog(Exception excp) {
		String errorlog = "errorlog.txt";
		String savePath = "";
		String logFilePath = "";
		FileWriter fw = null;
		PrintWriter pw = null;
		try {
			//判断是否挂载了SD卡
			String storageState = Environment.getExternalStorageState();		
			if(storageState.equals(Environment.MEDIA_MOUNTED)){
				savePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/netmoon/Log/";
				File file = new File(savePath);
				if(!file.exists()){
					file.mkdirs();
				}
				logFilePath = savePath + errorlog;
			}
			//没有挂载SD卡，无法写文件
			if(logFilePath == ""){
				return;
			}
			File logFile = new File(logFilePath);
			if (!logFile.exists()) {
				logFile.createNewFile();
			}
			fw = new FileWriter(logFile,true);
			pw = new PrintWriter(fw);
			pw.println("--------------------"+(new Date().toLocaleString())+"---------------------");	
			excp.printStackTrace(pw);
			pw.close();
			fw.close();
		} catch (Exception e) {
			e.printStackTrace();		
		}finally{ 
			if(pw != null){ pw.close(); } 
			if(fw != null){ try { fw.close(); } catch (IOException e) { }}
		}

	}
	
	public static AppException http(int code) {
		return new AppException(TYPE_HTTP_CODE, code, null);
	}
	
	public static AppException http(Exception e) {
		return new AppException(TYPE_HTTP_ERROR, 0 ,e);
	}

	public static AppException socket(Exception e) {
		return new AppException(TYPE_SOCKET, 0 ,e);
	}
	
	public static AppException io(Exception e) {
		if(e instanceof UnknownHostException || e instanceof ConnectException){
			return new AppException(TYPE_NETWORK, 0, e);
		}
		else if(e instanceof IOException){
			return new AppException(TYPE_IO, 0 ,e);
		}
		return run(e);
	}
	public static AppException xml(Exception e) {
		return new AppException(TYPE_XML, 0, e);
	}
	public static AppException json(Exception e) {
		return new AppException(TYPE_JSON, 0, e);
	}	
	public static AppException createNetworkException(Exception e ,String msg) {
		if(msg!=null){
			return new AppException(TYPE_NETWORK, 0, e,msg);
		}else if(e instanceof UnknownHostException ){
			return new AppException(TYPE_NETWORK, 0, e,"找不到服务器");
		}else if(e instanceof ConnectException){
			return new AppException(TYPE_NETWORK, 0, e,"连接失败");
		}else if(e instanceof UnsupportedEncodingException){
			return new AppException(TYPE_NETWORK, 0, e,"服务器返回异常");
			//return new AppException(TYPE_NETWORK, 0, e,"编码异常");
		}else if(e instanceof MalformedURLException){
			return new AppException(TYPE_NETWORK, 0, e,"请求的URL地址有误");	
		}else if(e instanceof ClientProtocolException){
			return new AppException(TYPE_NETWORK, 0, e,"发生请求错误");
		}
		else if(e instanceof HttpException){
			return http(e);
		}else if(e instanceof SocketException){
			return socket(e);
		}
		return http(e);
	}
	public static AppException run(Exception e) {
		return new AppException(TYPE_RUN, 0, e);
	}
	
}
