package com.wasu.cs.widget.viplogin;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.http.SslError;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.SslErrorHandler;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebSettings.RenderPriority;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;

import com.wasu.comp.wasuwebview.WR;
import com.wasu.comp.wasuwebview.WR_Favorites;
import com.wasu.comp.wasuwebview.WR_History;
import com.wasu.comp.wasuwebview.WR_Term;
import com.wasu.comp.wasuwebview.WR_UserCenter;
import com.wasu.comp.wasuwebview.tv;
import com.wasu.module.log.WLog;

/**
 * 屏蔽了goBack()的webView，用在用户登录，支付窗口，这些窗口不需要goBack()
 * danxingxi
 */
public class WasuVipWebView extends WebView {
	private static final String TAG = "WasuWebView";
	
	/**
	 * 回调外部状态
	 */
	private IWebStatusListener mUserCenterListener;
	
	private boolean mbLoadError = false;
	
	/**
	 * 网页加载超时时间
	 */
	public static final int WEB_LOAD_TIMEOUT = 10000;
	
	/** 因为键值交给详情页处理，当网页不能响应的时候，需要强制退出 **/
	private int MAX_FORCE_BACK_COUNT = 2;
	private int mCurBackCount = 0;
	
	public interface IWebStatusListener {
		/** 加载状态 **/
		public static final int PAGE_START			= 1; //页面开始加载或者内部页面开始跳转
		public static final int PAGE_FINISH			= 2; //页面加载完成或者内部页面加载完成
		public static final int PAGE_LOAD_TIMEOUT	= 3; //页面加载超时
		public static final int PAGE_LOAD_ERROR		= 4; //页面加载出错
		
		public void onWasuWebInfo(int code, String extra);
	}
	
	public WasuVipWebView(Context context) {
		super(context);
		initWebView();
	}
	
	public WasuVipWebView(Context context, AttributeSet attrs) {
		super(context, attrs);
		throw new IllegalAccessError("目前只支持动态创建");
	}
	
	public WasuVipWebView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		throw new IllegalAccessError("目前只支持动态创建");
	}
	
	/**
	 * 设置状态监听
	 * @param l
	 */
	public void setOnUserCenterListener(IWebStatusListener l){
		mUserCenterListener = l;
	}
	
	/**
	 * 用于向外部抛状态信息 
	 * @param code
	 * @param extra
	 */
	private void postInfo(int code, String extra){
		if (mUserCenterListener != null){
			mUserCenterListener.onWasuWebInfo(code, extra);
		}
	}
	
	/**
	 * 初始化web容器
	 */
	@SuppressLint("SetJavaScriptEnabled")
	private void initWebView() {
		setBackgroundColor(0);
		setLayerType(WebView.LAYER_TYPE_SOFTWARE, null);
		WebSettings webSettings = getSettings();
		webSettings.setLoadWithOverviewMode(true);
		webSettings.setUseWideViewPort(true);
		webSettings.setNeedInitialFocus(false);
		webSettings.setSupportMultipleWindows(true);
		webSettings.setAppCacheEnabled(true);
		webSettings.setDefaultTextEncodingName("UTF-8");
		webSettings.setBuiltInZoomControls(true);

		webSettings.setJavaScriptEnabled(true);
		webSettings.setAllowFileAccess(true);
		webSettings.setSupportZoom(false);
		webSettings.setDatabaseEnabled(true);
		webSettings.setDomStorageEnabled(true);
		webSettings.setAllowContentAccess(true);
		webSettings.setRenderPriority(RenderPriority.HIGH);

		// 禁用某些机型上面长按OK键会弹出复制粘贴的上下文菜单
		setOnLongClickListener(new OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				return true;
			}

		});
		
		setWebChromeClient(new WebChromeClient(){
			@Override
			public void onReceivedTitle(WebView view, String title) {
				super.onReceivedTitle(view, title);
				
				if (!TextUtils.isEmpty(title)){
					if (title.compareToIgnoreCase("404 NOT FOUND") == 0 ||
						title.indexOf("page cannot be found") >= 0 ||
						title.indexOf("502 Bad Gateway") >= 0 ||
						title.indexOf("504 Gateway Time-out") >= 0 ||
						title.indexOf("找不到网页") >= 0 ||
						title.indexOf("HTTP Status") >= 0){
						removeCallbacks(timeOutTask);
						mbLoadError = true;
						postInfo(IWebStatusListener.PAGE_LOAD_ERROR, null);
					}
				}
			}
		});

		setWebViewClient(new WebViewClient() {

            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
                if (url.startsWith("http://61.160.200.252")) {
                    WLog.d("web", "11111 shouldInterceptRequest resource:" + url);
                    return new WebResourceResponse(null, null, null);
                }
                return super.shouldInterceptRequest(view, url);
            }

			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				mbLoadError = false;
				loadUrl(url);
				return true;
			}

			@Override
			public void onPageStarted(WebView view, String url, Bitmap favicon) {
				WLog.d(TAG, "start load page:" + url);
				postInfo(IWebStatusListener.PAGE_START, null);
				removeCallbacks(timeOutTask);
				postDelayed(timeOutTask, WEB_LOAD_TIMEOUT);
			}

			@Override
			public void onPageFinished(WebView view, String url) {
				WLog.d(TAG, "finish load page:" + url);
				postInfo(IWebStatusListener.PAGE_FINISH, null);
				removeCallbacks(timeOutTask);
			}

			@Override
			public void onLoadResource(WebView view, String url) {
//				WLog.d(TAG, "loading resource:" + url + " at " + System.currentTimeMillis());
			}

			@Override
			public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
				mbLoadError = true;
				Toast.makeText(getContext(), "加载失败，请稍后访问", Toast.LENGTH_SHORT).show();
				WLog.d(TAG, "load error:" + failingUrl + "(" + errorCode + ")");
				goBack();
			}
			
			@Override
			public void onReceivedSslError(WebView view,
					SslErrorHandler handler, SslError error) {
				handler.proceed();
			}
		});
	}
	
	/**
	 * 注入js基本对象
	 */
	public void injectBaseJsObject() {
		addJavascriptInterface(new WR(getContext()), "WR");
		addJavascriptInterface(new WR_Term(getContext(), this), "WR_Term");
		addJavascriptInterface(new WR_History(getContext()), "WR_History");
		addJavascriptInterface(new WR_Favorites(getContext()), "WR_Favorites");
		addJavascriptInterface(new tv(getContext()), "tv");
		addJavascriptInterface(new WR_UserCenter(getContext()), "WR_UserCenter");
	}
	
	@Override
	public void goBack() {
		removeCallbacks(timeOutTask);
		postInfo(IWebStatusListener.PAGE_FINISH, null);
		super.goBack();
	}
	
	/**
	 * 设置快速按几次后强制退出
	 * @param count
	 */
	public void setMaxForceBackCount(int count){
		MAX_FORCE_BACK_COUNT = count;
	}
	
	private Runnable mResettBackTimer = new Runnable() {
		@Override
		public void run() {
			mCurBackCount = 0;
		}
	};
	
	@Override
	public boolean dispatchKeyEvent(KeyEvent event) {
		int keyCode = event.getKeyCode();
		WLog.d(TAG, "dispatchKeyEvent, event: " + event.getAction() + ";code: " + keyCode);
		if (event.getAction() == KeyEvent.ACTION_DOWN && event.getKeyCode() == KeyEvent.KEYCODE_BACK){
			removeCallbacks(mResettBackTimer);
			if (mbLoadError || ++mCurBackCount == MAX_FORCE_BACK_COUNT){
				mCurBackCount = 0;
				if(canGoBack()){
					// 目前用户扫码登录也是用的这个webview，在网络不好的情况下回存在按返回键后没有关闭窗口而是再次加载了二维码，
					// 导致用户需要按多次返回键才可以返回，这里用作加载登录或者支付页面，一按返回键就直接返回关闭窗口，不需要返回的时候加载上次加载的内容
					// 所以这里屏蔽goBack()方法，danxingxi
//					goBack();
//					return true;
					return super.dispatchKeyEvent(event);
				}else{
					return super.dispatchKeyEvent(event);
				}
			}

			postDelayed(mResettBackTimer, 300);
		}
		if (event.getAction() == KeyEvent.ACTION_DOWN) {
			int jsKeyCode = converseKey2JsKey(keyCode);
			if (jsKeyCode != -1) {
				loadUrl("javascript:" + composeJsKeyStr(jsKeyCode));
				return true;
			}
		}
		
		return super.dispatchKeyEvent(event);
	}
	
	private int converseKey2JsKey(int keyCode) {
		int jsKeyCode;
		switch (keyCode) {
		case KeyEvent.KEYCODE_DPAD_UP:
			jsKeyCode = 38;
			break;
		case KeyEvent.KEYCODE_DPAD_DOWN:
			jsKeyCode = 40;
			break;
		case KeyEvent.KEYCODE_DPAD_LEFT:
			jsKeyCode = 37;
			break;
		case KeyEvent.KEYCODE_DPAD_RIGHT:
			jsKeyCode = 39;
			break;
		case KeyEvent.KEYCODE_DPAD_CENTER:
		case KeyEvent.KEYCODE_ENTER:
			jsKeyCode = 13;
			break;
		case KeyEvent.KEYCODE_BACK:
			jsKeyCode = 340;
			break;
		case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
		case KeyEvent.KEYCODE_MEDIA_REWIND:
			jsKeyCode = 372;
			break;
		case KeyEvent.KEYCODE_MEDIA_NEXT:
		case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
			jsKeyCode = 373;
			break;
		case KeyEvent.KEYCODE_VOLUME_UP:
			jsKeyCode = 101;
			break;
		case KeyEvent.KEYCODE_VOLUME_DOWN:
			jsKeyCode = 102;
			break;
		default:
			jsKeyCode = -1;
			break;
		}
		return jsKeyCode;
	}
	
	/**
	 * 组装发送键值的js代码
	 * 
	 * @param jsKeyCode
	 * @return
	 */
	private String composeJsKeyStr(int jsKeyCode) {
		String keyPressString = "var event = document.createEvent('Events');" + "event.initEvent('keydown',true,true);" + "event.view = document.defaultView;" + "event.altKey = false;" + "event.ctrlKey = false;" + "event.shiftKey = false;" + "event.metaKey = false;"
				+ "event.keyCode = " + jsKeyCode + ";" + "event.charCode = " + jsKeyCode + ";" + "event.which = " + jsKeyCode + ";" + "document.body.dispatchEvent(event);";
		return keyPressString;
	}
	
	/**
	 * 网页加载超时task
	 */
	private Runnable timeOutTask = new Runnable() {
		@Override
		public void run() {
			mbLoadError = true;
			postInfo(IWebStatusListener.PAGE_LOAD_TIMEOUT, null);
		}
	};

	/**
	 * 重置返回键计数器
	 * danxingxi
	 */
	public void resetBackCount(){
		WLog.d("web", TAG+" resetWebView");
		removeCallbacks(mResettBackTimer);
		mbLoadError = false;
		mCurBackCount = 0;
	}
}
