package jp.agentec.abook.abv.ui.common.activity;

import jp.agentec.abook.abv.bl.acms.type.DownloadStatusType;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.exception.ABVException;
import jp.agentec.abook.abv.bl.common.exception.ABVExceptionCode;
import jp.agentec.abook.abv.bl.common.exception.AcmsException;
import jp.agentec.abook.abv.bl.common.exception.NetworkDisconnectedException;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.download.ContentDownloader;
import jp.agentec.abook.abv.bl.download.ContentFileExtractor;
import jp.agentec.abook.abv.bl.download.ContentZipDownloadNotification;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.cl.helper.ContentMarkingFileHelper;
import jp.agentec.abook.abv.cl.util.AndroidStringUtil;
import jp.agentec.abook.abv.launcher.android.ABVApplication;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.constant.ErrorCode;
import jp.agentec.abook.abv.ui.common.constant.NaviConsts;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.home.activity.ABookSettingActivity;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.animation.Animation;
import android.view.animation.LinearInterpolator;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.handmark.pulltorefresh.library.PullToRefreshBase;

public abstract class ABVUIActivity extends ABVAuthenticatedActivity {
	private final static String TAG = "ABVUIActivity";

	private boolean startRefresh; //自動リフレッシュはネットワークエラー表示しないように    
	protected ImageView mRefreshImage; // add by jang
	protected TextView mUpdatedDate; // add by jang
	protected TextView mLoadingText; // add by jang;

	// 新着更新処理の終了後、プルダウンを完了させるためのビュー
	protected PullToRefreshBase refreshBaseView;

	protected String urlPassword; // Reader用
	//Gettisの場合：プッシュ―メッセージを経由してコンテンツダウンロード場合対応
	private String mPushMessage = ""; //コンテンツ追加の機能をの引数が増えないようにこの変数を追加

    private boolean isCheckTransferMaster = false; // マスター転送が同時実行されることを防ぐためのチェック

	protected boolean mAutoBatchSyncFlg = false; //自動一括同期処理フラグ

	@Override
    protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//Bug #50460対応（プッシュメッセージ受信後のダイアログ表示時、Android8.0のみ問題発生するので、チェックして画面固定処理しない）
		if (this instanceof ShowPushMessageDailogActivity) {
			if (android.os.Build.VERSION.SDK_INT != Build.VERSION_CODES.O) {
				setPortraitIfNormal();
			}
		} else {
			setPortraitIfNormal();
		}
		startRefresh = true;
        ABVEnvironment.getInstance().enableToastMessage = true;
//		dateFormat ="yyyy'" + getResources().getString(R.string.date_format_year) + "'MM'" + getResources().getString(R.string.date_format_month) + "'dd'" + getResources().getString(R.string.date_format_day) + "'HH:mm:ss";
	}
	
	//更新する場合中止させる。
	protected boolean refreshStop() {
		if (refreshFlag()) {
			try {
				contentRefresher.stopRefresh();
				
			} catch (Exception e) {
				Logger.w("stopRefresh failed at refreshStop.", e);
				
				//	停止ができなかった場合はfalseを返す。
				return false;
			}
		}
		return true;
 	}
	
	//更新の場合動作させないメッセージ
	protected boolean refreshMessage() {
		if (refreshFlag()) {
			handleErrorMessageToast(ErrorCode.L113);
			return true;
		}else{
			return false;
		}
 	}

	//更新中の場合true
	protected boolean refreshFlag() {
//		if (progressRefresh.getVisibility() == View.VISIBLE) {
//			return true;
//		}else{
//			return false;
//		}
		return false;
 	}

	@Override
	protected void onResume() {
		super.onResume();
	}
	
	@Override
	protected void onPause() {
		super.onPause();
	}

	@Override
	protected void onStop() {
		super.onStop();
	}
	
	@Override
	protected void onDestroy() {
		super.onDestroy();
		//キャッシュを使用しない場合、ディレクトリが残っていれば削除
		if (!getRBoolean(R.bool.use_cache)) {
			ContentFileExtractor.getInstance().removeAllContentCash();
		}
	}

	@Override
    protected void startActivity(Intent intend, NaviConsts ABVNavi) {
		super.startActivity(intend, ABVNavi) ;   
		closeProgressPopup();
    }
	 
	
	@Override
    protected void startActivityForResult(Intent intend, int requestCode, NaviConsts ABVNavi) {
		super.startActivityForResult(intend,requestCode, ABVNavi);
		closeProgressPopup();
    }
	
	@Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {
		closeProgressPopup();
		return super.onKeyUp(keyCode, event);
		
	}
	
	public boolean refreshContent(boolean isAutoRefresh) throws NetworkDisconnectedException {
		boolean result = true;
		try {
			result = contentRefresher.isRefreshing();
			
			Logger.d(TAG, "contentDownloader.isRefreshing() %s", result);
			getABVUIDataCache().preIsCatalogEdition = ABVDataCache.getInstance().serviceOption.isCatalogEdition();

			if (!result) {
				startUpdateAnimation();
				// contentDownloadObserverがnullだと更新マークのアニメーションが完了しない TODO 2014/11/12 Jang
				// onCreateでrefresh処理をcallしたときに起きる

				contentRefresher.refreshContentList(this);
			}
		} catch (NetworkDisconnectedException e) {
			refreshContentException();
			if (startRefresh) {
				startRefresh = false;
			}
			throw e;
		} catch (ABVException e) {
			refreshContentException();
			//noinspection EnumSwitchStatementWhichMissesCases
			switch (e.getCode()) {
			case C_I_CONTENT_0001:
				handleErrorMessageToast(ABVExceptionCode.C_I_CONTENT_0001);
				break;
			case S_E_ACMS_1403:
				// 再ログイン
				onAuthenticationFailed();
				break;
			case C_I_CONTENT_0002:
				//	コンテンツダウンロード中は自動更新を行わない。
				if (!isAutoRefresh) {
					handleErrorMessageToast(ABVExceptionCode.C_I_CONTENT_0002);
				}
				break;
			case S_E_ACMS_0500:
				handleErrorMessageToast(ABVExceptionCode.S_E_ACMS_0500);
				break;
			case S_E_ACMS_INVALID_RESPONSE:
				// サーバー通信エラー時、エラーメッセージ表示
				handleErrorMessageToast(ABVExceptionCode.S_E_ACMS_INVALID_RESPONSE);
				break;
			default:
				Logger.e(TAG, "Exception DataRefresh", e);
				handleErrorMessageToast(ErrorCode.E107);
				break;
			}
		} catch (Exception e) {
			refreshContentException();
			Logger.e(TAG, "Exception DataRefresh", e);
			handleErrorMessageToast(ErrorCode.E107);
		}
		
		return result;
	}

	/**
	 * 新着更新中に例外が発生したら、行う処理
	 */
	private void refreshContentException() {
		stopUpdateAnimation();
		//自動一括同期処理のため、新着更新した時にインジケーター非表示
		if (mAutoBatchSyncFlg) {
			mAutoBatchSyncFlg = false;
			closeProgressPopup();
		}
	}
	/**　
	 *　グリッド初期化
	 * onCreateでは呼ばないないこと！！
	 * @param isAutoRefresh 自動リフレッシュフラグ
	 * @throws Exception 
	 * @throws ABVException 
	 * @throws NetworkDisconnectedException 
	 * @since 1.0.0
	 */
	protected boolean dataRefresh(boolean isAutoRefresh) {
		try {
			return refreshContent(isAutoRefresh);
		} catch (NetworkDisconnectedException e) {
			Logger.e(TAG, "NetworkDisconnectedException" + e);
			
			//自動リフレッシュでない場合メッセージ表示
			if (!isAutoRefresh) {
				handleErrorMessageToast(ErrorCode.NETWORK);
			}
		}
		return false;
	}

	
//	// @{ABVAuthenticatedActivity.contentLinkCheckDeliverable}と同じ
//	//非公開と期間終了のコンテンツがある場合削除
//	protected boolean contentCheckDeliverable(long contentId) throws AcmsException, NetworkDisconnectedException  {
//		boolean result = true;
//			// サーバ側でコンテンツがダウンロード出来ない状態(非公開、削除など)の時はメッセージを表示
//			ContractLogic contractLogic = AbstractLogic.getLogic(ContractLogic.class);
//    		if (!contentLogic.getContentCheckDeliverable(contentId)) {
//    			if (contractLogic.getNoAuthDelete()) {
//    				ContentDto contentDto = contentDao.getContent(contentId);
//    				
//    				if (contentDto != null) {
//    					contentLogic.deleteContent(contentDao.getContent(contentId), true);
//					}
//    			}
//    			result = false;
//    		}
//		return result;
//	}
	
	/**
	 * コンテンツの有効性チェックとダウンロードを行う
	 * @param contentId 対象コンテンツID
	 * @return boolean チェックの成功可否
	 */
	@Override
    public boolean contentValidCheckAndDownload(final long contentId) {
		CommonExecutor.execute(new Runnable() {
			@Override
			public void run() {
				contentValidCheckAndDownload(contentId, true);
			}
		});
		return true;
	}
	
	/**
	 * コンテンツの有効性チェックとダウンロードを行う
	 * @param contentId 対象コンテンツID
	 * @param refreshFlag 画面のリフレッシュさせるかのフラグ
	 * @return boolean チェックの成功可否
	 */
	public boolean contentValidCheckAndDownload(long contentId, boolean refreshFlag) {
		boolean checkResult = false;
		int status = contentValidCheckAndShowMessage(contentId, MessageType.TYPE_SHOW_TOAST);
		if (status == ContentCheckResultType.SUCCESS) {
			checkResult = contentDownload(contentId);
		}
		
		if (status == ContentCheckResultType.NO_AUTH_DELETE && refreshFlag) {
			// コンテンツのチェック結果が権限喪失の場合はリフレッシュ
			handler.post(new Runnable() {
				@Override
				public void run() {
					dataRefresh(true);
				}
			});
		}
		return checkResult;
	}
	

	// コンテンツダウンロード一時停止
	public void contentDownloadPause(long contentId) {
		contentDownloader.pause(contentId, false);
	}

	// コンテンツダウンロード再開
	public boolean contentDownloadResume(ContentDto contentDto) {
		long contentId = contentDto.contentId;
		boolean result = true;
		try {
			int status = contentValidCheckAndShowMessage(contentId, MessageType.TYPE_SHOW_TOAST);
			if (status == ContentCheckResultType.SUCCESS) {
				contentDownloader.resume(contentId);
			} else if (status == ContentCheckResultType.NETWORK_ERROR) {
				result = false;
			} else {
				contentDownloadCancel(contentDto);
				result = false;
			}

			if (status == ContentCheckResultType.NO_AUTH_DELETE) {
				// コンテンツのチェック結果が権限喪失の場合はリフレッシュ
				handler.post(new Runnable() {
					@Override
					public void run() {
						dataRefresh(true);
					}
				});
			}
		} catch (NetworkDisconnectedException e) {
			Logger.e(TAG, "NetworkDisconnectedException" + e);
			handleErrorMessageToast(ErrorCode.NETWORK);
			result = false;
		} catch (AcmsException e) {
			Logger.e(TAG, "AcmsException", e);
			handleErrorMessageToast(e);
			result = false;
		}
		return result;
	}

	// コンテンツダウンロードキャンセル
	public void contentDownloadCancel(final ContentDto contentDto) {
		CommonExecutor.execute(new Runnable() {
			@Override
			public void run() {
				contentDownloader.cancel(contentDto.contentId);
			}
		});
	}

	// ダウンロード済みコンテンツ削除
	public boolean contentDelete(ContentDto contentDto) {
		boolean result = true;
		try {
			deleteContent(contentDto, false);
		} catch (Exception e) {
			result = false;
			Logger.e("Exception ", e);
			handleErrorMessageToast(ErrorCode.E107);
		}
		if(result) {
			// クリップボードのコンテンツが削除されたらクリア
			if (getABVUIDataCache().srcContentId == contentDto.contentId) {
				getABVUIDataCache().srcContentId = -1;
			}
		}
		return result;
	}

    /**
     * setTheme不具合によりタブレットデザインではDialogThemeを使う場合のAcitivity名をルールとして語尾にDialogをつける
     * @param className
     * @return
     */
    protected String convertClassName(String className) {
    	if (!isNormalSize()) {
    		className += "Dialog";
    	}
    	return className;
    }
    
	protected void startUpdateAnimation() {
		Logger.d(TAG, "startUpdateAnimation");
		RotateAnimation mRefreshAnimation = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
		mRefreshAnimation.setInterpolator(new LinearInterpolator());
		mRefreshAnimation.setDuration(1200);
		mRefreshAnimation.setRepeatCount(Animation.INFINITE);
		mRefreshAnimation.setRepeatMode(Animation.RESTART);

		if (mRefreshImage != null) {
			mRefreshImage.startAnimation(mRefreshAnimation);
		} else {
			Logger.w(TAG, "you need to set mRefreshImage.");
		}
	}
    
	protected void stopUpdateAnimation() {
		Logger.d(TAG, "stopUpdateAnimation");
		if (mRefreshImage != null) {
			mRefreshImage.clearAnimation();
		} else {
			Logger.w(TAG, "you need to set mRefreshImage.");
		}

		// ヘッダーの新着更新処理を完了にさせる
		if (refreshBaseView != null) {
			handler.post(new Runnable() {
				@Override
				public void run() {
					refreshBaseView.onRefreshComplete();
				}
			});
		}

		// 自動ダウンロード対象がある場合、新着更新が完了したあとに開始するように修正(jang)
		ContentDownloader.getInstance().autoDownload();
	}

	/**
	 * メモ・マーキング・しおりをコピーします
	 * 
	 * @param srcContentId コピー元コンテンツID
	 * @param dstContentId コピー先コンテンツID
	 */
	protected void copyUserInfoCheckOrientation(final long srcContentId, final long dstContentId) {
		ContentDto srcContentDto = contentDao.getContent(srcContentId);
		ContentDto dstContentDto = contentDao.getContent(dstContentId);

		// コンテンツの向きが違う場合、アラートを表示
        if (srcContentDto.orientation == dstContentDto.orientation) {
            copyUserInfo(srcContentId, dstContentId);
        } else {
            ABookAlertDialog dialog = AlertDialogUtil.createAlertDialog(this, R.string.user_info_copy);
            dialog.setMessage(R.string.user_info_copy_alert);
            dialog.setNegativeButton(R.string.no, null);
            dialog.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    copyUserInfo(srcContentId, dstContentId);
                }
            });
            showAlertDialog(dialog);
        }
	}

	private void copyUserInfo(long srcContentId, long dstContentId) {
		StringBuffer sbErrorMessage = new StringBuffer();

		// メモのコピー
		memoLogic.copyContentMemo(srcContentId, dstContentId);

		try {
			// マーキングのコピー
			ContentMarkingFileHelper markingFileHelper = new ContentMarkingFileHelper();
			markingFileHelper.copyMarkingFile(srcContentId, dstContentId);
		} catch (Exception e) {
			if (sbErrorMessage.length() > 0) {
				sbErrorMessage.append(",");
			}
			sbErrorMessage.append(getString(R.string.marking));
			Logger.e(TAG, e.toString());
		}

		try {
			// しおりのコピー
			bookmarkLogic.copyContentBookmark(srcContentId, dstContentId);
		} catch (Exception e) {
			if (sbErrorMessage.length() > 0) {
				sbErrorMessage.append(",");
			}
			sbErrorMessage.append(getString(R.string.bookmark));
			Logger.e(TAG, e.toString());
		}

		// エラーが起きている場合メッセージを表示する
		if (sbErrorMessage.length() > 0) {
			sbErrorMessage.append(getString(R.string.paste_memo));
			ABVToastUtil.showMakeText(this, AndroidStringUtil.format(this, R.string.failed_state, sbErrorMessage.toString()), Toast.LENGTH_SHORT);
		} else {
			ABVToastUtil.showMakeText(this, AndroidStringUtil.format(this, R.string.complete_state, R.string.paste_memo), Toast.LENGTH_SHORT);
		}
	}

	@Override
	public void onDownloadingContentZip(final ContentZipDownloadNotification notification) {
		super.onDownloadingContentZip(notification);
		if (notification.downloadStatus == DownloadStatusType.Paused || notification.downloadStatus == DownloadStatusType.AutoPaused || notification.downloadStatus == DownloadStatusType.Failed) {
			//プッシュ―メッセージでコンテンツダウンロードの場合：ダウンロード中に何か問題が起きたら自動的にコンテンツ開かない
			((ABVApplication)getApplication()).setAutoOpenAfterDownloadContent(false);
		}
	}

	// 設定画面表示
	public void showSetting() {
		Intent intent = new Intent();
		intent.setClassName(getApplicationContext().getPackageName(), ABookSettingActivity.class.getName());
		intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
		// 設定画面の前のActivityを保存する（設定画面から戻る用）
		ActivityHandlingHelper.getInstance().setPreviousOfSettingActivity(this);
		startActivity(intent);
		// ※ 設定画面からログアウトした場合、このActivityも残らないようにfinishして遷移する
		finish();
	}
}
