package jp.agentec.abook.abv.ui.home.activity;
/**
 * GuideViewActivity.java
 * @author jang
 */

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.SparseArray;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;

import com.foxit.sdk.PDFException;

import org.json.adf.JSONArray;
import org.json.adf.JSONException;
import org.json.adf.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import jp.agentec.abook.abv.bl.acms.client.json.DownloadedContentInfoJSON;
import jp.agentec.abook.abv.bl.acms.client.json.MarkingJson;
import jp.agentec.abook.abv.bl.acms.client.json.content.ActionInfoJSON;
import jp.agentec.abook.abv.bl.acms.client.json.content.ContentJSON;
import jp.agentec.abook.abv.bl.acms.client.json.content.PDFLinkJSON;
import jp.agentec.abook.abv.bl.acms.client.json.content.PageInfoJSON;
import jp.agentec.abook.abv.bl.acms.client.json.content.PageInfoJSON.PageInfoJSONData;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.common.util.JsonUtil;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.ContentDao;
import jp.agentec.abook.abv.bl.data.dao.ContentPageDao;
import jp.agentec.abook.abv.bl.download.ContentFileExtractor;
import jp.agentec.abook.abv.bl.dto.ContentDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.ContentReadingLogLogic;
import jp.agentec.abook.abv.bl.websocket.MeetingManager;
import jp.agentec.abook.abv.cl.environment.DeviceInfo;
import jp.agentec.abook.abv.cl.helper.ContentMarkingFileHelper;
import jp.agentec.abook.abv.cl.util.BitmapUtil;
import jp.agentec.abook.abv.cl.util.ContentLogUtil;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.PDFFileProvider;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.launcher.android.R.id;
import jp.agentec.abook.abv.ui.common.activity.ABVContentViewActivity;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType.DefPrefKey;
import jp.agentec.abook.abv.ui.common.appinfo.options.Options;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.helper.ABVViewUnbindHelper;
import jp.agentec.abook.abv.ui.common.util.ABVToastUtil;
import jp.agentec.abook.abv.ui.common.util.AlertDialogUtil;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.common.view.ABVPopupListWindow;
import jp.agentec.abook.abv.ui.common.vo.Size;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;
import jp.agentec.abook.abv.ui.Interface.MovePageInterface;
import jp.agentec.abook.abv.ui.Interface.UnAuthorizedContentListener;
import jp.agentec.abook.abv.ui.viewer.foxitPdf.FoxitPdfCore;
import jp.agentec.abook.abv.ui.viewer.foxitPdf.PDFPageView;
import jp.agentec.abook.abv.ui.viewer.foxitPdf.PdfImageProvider;
import jp.agentec.abook.abv.ui.viewer.view.ABVMediaPlayer;
import jp.agentec.abook.abv.ui.viewer.view.Action3DImageView;
import jp.agentec.abook.abv.ui.viewer.view.EnqueteLayout;
import jp.agentec.abook.abv.ui.viewer.view.EnqueteWebView;
import jp.agentec.abook.abv.ui.viewer.view.FullVideoView;
import jp.agentec.abook.abv.ui.viewer.view.MarkingLayout;
import jp.agentec.abook.abv.ui.viewer.view.MarkingView;
import jp.agentec.abook.abv.ui.viewer.view.PageScrollView;
import jp.agentec.abook.abv.ui.viewer.view.PageView;
import jp.agentec.abook.abv.ui.viewer.view.ThumbnailSeekBarLayout;
import jp.agentec.abook.abv.ui.viewer.view.ZoomRelativeLayout;
import jp.agentec.abook.abv.ui.viewer.view.ZoomRelativeLayout.ViewMargin;
import jp.agentec.abook.abv.ui.viewer.view.action.PageActionList;
import jp.agentec.abook.abv.ui.viewer.view.action.TapMediaPlayer;
import jp.agentec.abook.abv.ui.viewer.view.action.VideoMountAction;
import jp.agentec.adf.util.DateTimeUtil;
import jp.agentec.adf.util.DateTimeUtil.DateUnit;
import jp.agentec.adf.util.StringUtil;

public class GuideViewActivity extends ABVContentViewActivity {
	private static final String TAG = "GuideViewActivity";

	/**
	 * mMainLayout > mPageScrollView > mContentWrapLayout
	 */
	private MmainLayout mMainLayout; // メインレイアウト
	private PageScrollView mPageScrollView; // ページスクロールのためのカスタマイズスクロールビュー
	private RelativeLayout mContentWrapLayout; // 各ページを保持しているViewGroup
	private MarkingLayout mMarkingLayout; // マーキングレイアウト

	/**
	 * mMainLayout > mMarkingLayout
	 * 		-mToolBar
	 * 		-mPageScrollView
	 * 		-mPageNumberLayout
	 * 		-mLargeImageView
	 * 		-mSeekBarLayout
	 */
	private View mToolBar; // ツールバー
	private RelativeLayout mPageNumberLayout; // ページ番号
	private ImageView mLargeImageView;
	private ThumbnailSeekBarLayout mSeekBarLayout; // ページスライスバー
	private int mLThumViewSize;
	public static final int THUMB_STICK_SIZE = 10;


	private ContentJSON mContentJSON; // コンテンツのJSONデータ
	private PageInfoJSON mPageInfoJSON; // オーサリング画面の各ページサイズのJSONデータ
	private Size mBaseFileSize;
	private ContentDto mContentDto;

	private float mMinDistance;// Scroll移動距離チェック時の最小移動距離値
	private float mScrollDistance; // 実際にスクロールかけた移動距離

//	private float mDisplayScale; // iPad用としてオーサリングされた座標やサイズをAndroid用に変換するためのスケール

	private int mAllPageCount = 1; // 全ページ数

	private GestureDetector mActivityGestureDetector; // フリックやスクロールジェスチャーを感知する。通常のScrollViewはページ遷移できないため。
	private ScrollStatus mScrollStatus = ScrollStatus.NONE;

	private long mFromOverEventPointTime = System.currentTimeMillis(); // 前回スクロール（フリック）した時間（連続フリックを制する為）

	/** Audio関連 **/
	private ABVMediaPlayer contentBGMPlayer;
	private ABVMediaPlayer pageBGMPlayer;
	private TapMediaPlayer tapPlayer;
	private SparseArray<String> pageBGMPathList;
	private ArrayList<PageActionList> mPageActionList;

	private ToggleButton tbtnMarking;

	private boolean isSeeking = false;
	private boolean isMarking = false;
	private boolean isVideoMax = false;

	private boolean isLandscapeView;

	private static final int VIDEOVIEW = 100;
	private static final int WEBVIEW = 200;
	private static final int PREVIEW = 300;

	private List<MarkingView> mMarkingViewList;
	private boolean isAnotherViewOpenFlg = false;

	private int intervalAddOrRemovePage = 200;

	private ToggleButton slide ;

	//앙케이트 모드
	private EnqueteLayout enqueteLayout;

	private boolean isEnquete = false;
	private boolean isEnqueteLeft = false;
	private boolean isEnqueteFullScreen;
	private boolean isDisallowMovePage  = false;

	//앙케이트 공통화 설문일때 직전 EnqueteLayout을 저장
	//ym.chae
	private boolean touchFlg = false;

	//ym.chae
	public static HashMap<Long, EnqueteLayout> enqueteMap = new HashMap<>();

	//프리뷰 상태일때 Flag 값
	private boolean preViewFlg;

	//플레이 탭사운드 Flag 값
	private boolean playTapSoundFlg = false;

	//좌우 버튼 값 Flg
	private boolean moveBtnFlg = false;

	private boolean pageBgmFlg =false;
	private boolean contentsBgmFlg = false;
	private String contentsBgmFilePath=null;

	private FoxitPdfCore mFoxitPdfCore = null; // PDFレンダリング
	private PdfImageProvider mPdfImageProvider = null;

	private boolean hasMultiPages;

	private RelativeLayout overlapLayout;
	private View subscriberToolBar;
	private Button mExitBtn;
	private ImageButton mHistoryBtn;
	private ImageButton mBtnRemoteStart;
	private ConcurrentHashMap<Long, View> objectIdButtonMap = new ConcurrentHashMap<>();
	private SharedPreferences pref;

	private FullVideoView fullVideoView;

	private long availableImageBytePerPage;
	private boolean onCreateFinish = false; // カーソル連動に使用

	private SparseArray<ZoomRelativeLayout> mShowPageLayout = new SparseArray<>();

	private boolean isEnqueteOpening = false;

	/**
	 * スクロールステータス
	 */
	enum ScrollStatus {
		NONE,
		SCROLL,
		FLING
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		Logger.i(TAG, "[onCreate]:contentId=" + getContentId());
		super.onCreate(savedInstanceState);

		// 全画面表示
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);

		// 初期値設定
		pageBGMPathList = new SparseArray<>();
		mPageActionList = new ArrayList<>();
		mMarkingViewList = new ArrayList<>();
		mActivityGestureDetector = new GestureDetector(getApplicationContext(), mGestureListener);
		pref = PreferenceManager.getDefaultSharedPreferences(GuideViewActivity.this);

		//앙케이트 공통화 설문
		enqueteMap.clear();

		// 全体アクション情報などコンテンツ情報を保持するJSONデータ
		try {
			mContentJSON = contentLogic.getContentInfoJson(mContentDir, contentId);
		} catch (IOException e) {
			Logger.e(TAG,  "getContentInfoJson failed. contentDir=" + mContentDir, e);
		} catch (JSONException e) {
			Logger.e(TAG,  "getContentInfoJson failed. contentDir=" + mContentDir, e);
		}
		try {
			mFoxitPdfCore = initPdf(ContentFileExtractor.GUIDE_PDF_FILE_NAME);
		} catch (Exception e) {
			Logger.e(TAG, "initPdf error.", e);
		}
		if (mFoxitPdfCore == null) {
			// PDF読み込み失敗
			initError();
			return;
		}
		try {
			boolean isExistPassWord = mFoxitPdfCore.loadPDFDoc(null);
			if(isExistPassWord) {
				Logger.e(TAG, "pdf has password");
				initError();
				return;
			}
		} catch (PDFException e) {
			Logger.e(TAG, "FoxitPdfCore load failed.", e);
			initError();
			return;
		} catch (Exception e) {
			Logger.e(TAG, "read json failed.", e);
			initError();
			return;
		}

		try {
			mAllPageCount = mFoxitPdfCore.countPages();
			mBaseFileSize = new Size(mFoxitPdfCore.getPageSize(0));
		} catch (PDFException e) {
			Logger.e(TAG, "FoxitPdfCore getPageSize failed.", e);
			initError();
			return;
		}

		isLandscapeView = mBaseFileSize.width > mBaseFileSize.height;

		// 利用可能メモリ設定
		long maxMemory = Runtime.getRuntime().maxMemory();
		Logger.i(TAG, "maxMemory=" + maxMemory);
		availableImageBytePerPage = (long) (maxMemory * 0.8 / 3); // １ページあたりオーサリング・イメージに使用できるメモリ量（0.2は他のオブジェクトでの使用想定。3は3ページ分キャッシュするため） TODO: later ページごとに最適化

		// contentDtoをセット
		mContentDto = AbstractDao.getDao(ContentDao.class).getContent(contentId);
		// UI生成
		try {
			onCreateUIProcess();
		} catch (Exception e) {
			Logger.e(TAG, "onCreateUIProcess error.", e);
			initError();
			return;
		}

		if (!PreferenceUtil.get(this, DefPrefKey.DISPLAY_MARKING, true)) {
			tbtnMarking.setChecked(false);
		}

		onCreateFinish = true;

		ContentReadingLogLogic logic = AbstractLogic.getLogic(ContentReadingLogLogic.class);
		logic.prepareContentReadLog(contentId);
	}

	@Override
	protected void onResume() {
		Logger.i(TAG, "onResume");
		super.onResume();

		// コンテンツリンクから戻ってきた場合に参加者がコンテンツを開くためにonCreateからこちらに移動
		if (meetingManager.isSendable()) {
			meetingManager.sendWs(MeetingManager.CMD_OPEN, contentId, mCurrentPageNumber, null, null);
		}

		playPageBGMSound(mCurrentPageNumber);

		// ページ別ログ
		ContentLogUtil.getInstance().startContentPageReadLog(contentId, readingLogId, mCurrentPageNumber);

		// onCreateでviewが作成されている場合、readingLogIdが-1になってしまうので更新
		for (PageActionList pageActionList : mPageActionList) {
			for (VideoMountAction videoMountAction : pageActionList.arrayVideoMount) {
				videoMountAction.readingLogId = readingLogId;
			}
			for (VideoMountAction videoMountAction : pageActionList.arrayVideoChange) {
				videoMountAction.readingLogId = readingLogId;
			}
			for (Action3DImageView action3dImageView : pageActionList.array3DImage) {
				action3dImageView.readingLogId = readingLogId;
			}
		}
	}

	@Override
	public void finish() {
		Logger.i(TAG, "finish");

		contentDao.updateLastViewedPage(getContentId(), mCurrentPageNumber);
		// 携帯の場合、横コンテンツからTOPに戻るとSimpleSlideDrawerライブラリからエラーで落ちてしまうので、戻る前に縦向きに戻しておく
		setPortraitIfNormal();
		// 遠隔連動中に保存したマーキングファイルを削除
		ContentMarkingFileHelper contentMarkingFileHelper = new ContentMarkingFileHelper();
		contentMarkingFileHelper.deleteRemoteMarkingFile(contentId);
		super.finish();
	}

	protected void exitActivity() {
		Logger.d(TAG, "exitActivity");
		releaseInit();
		finish();
		ActivityHandlingHelper.getInstance().finishAllContentViewActivity();
	}

	/**　
	 *　横、縦の設定
	 * @since 1.0.0
	 */
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
		onCreateFinish = false;
		if (mShowedPopupWindow != null && mShowedPopupWindow.isShowing()) {
			mShowedPopupWindow.dismiss();
		}

		if (!mActivityFinishFlg) {// isRotatableはチェックしない
			Logger.d(TAG, "[onConfigurationChanged]:newConfig=" + newConfig);
			mShowPageLayout.clear();

			//noinspection VariableNotUsedInsideIf
			if (mContentWrapLayout != null) {
				removeViews();
			}
			if (mPageScrollView != null) {
				mPageScrollView.removeAllViews();
			}
			removeLargeThumView();

			if (mMainLayout != null) {
				mMainLayout.removeAllViews();
			}
			mPageActionList.clear();

			onCreateUIProcess();

		}

		if (isEnquete && enqueteLayout != null) { // アンケート入力値は維持する（回転固定するようにしたのでこの処理は意味がなくなった）
			EnqueteWebView webView = enqueteLayout.getWebView();
			ActionInfoJSON json = enqueteLayout.getActionInfoJSON(); // JSONException catch不要：すでにアンケートを表示しているので、throwされることは基本的にはない
			enqueteLayout.removeAllViews();
			showEnqueteLayout(webView, json);
		}
		else {
			isEnquete = false;
		}
		onCreateFinish = true;
	}


	private void onCreateUIProcess() {
		Logger.i(TAG, "mCurrentPageNumber=" +  mCurrentPageNumber);

		configureSize();

		mMainLayout = new MmainLayout(getApplicationContext());

		// ダミーのSurfaceViewを追加する。これを行わないとコンテンツの２ページ目に埋め込み動画がある場合は画面が一瞬真っ黒になる。
		// SurfaceViewをLayoutにaddViewするタイミングで起きるが、大きさ0のSurfaceViewをここでセットすることで避けられる。
		mMainLayout.addView(new SurfaceView(this), new ViewGroup.LayoutParams(0, 0));

		mContentWrapLayout = new RelativeLayout(getApplicationContext());

		mPageScrollView = new PageScrollView(getApplicationContext());
		mPageScrollView.setHorizontalScrollBarEnabled(false); // ScrollBarを非表示
		mPageScrollView.addView(mContentWrapLayout, new ViewGroup.LayoutParams(mAllPageCount * mDisplaySize.width, FP));

//        playPageBGMSound(0); // 1ページ目にペーいBGMがあった場合
		RelativeLayout.LayoutParams param0 = createParam(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
		param0.addRule(RelativeLayout.CENTER_IN_PARENT);
		mMainLayout.addView(mPageScrollView, param0);

		// ツールバー生成
		createToolBar();

		hasMultiPages = mAllPageCount > 1;
		if (hasMultiPages) { // サムネイルバーとページ番号表示
			mPageNumberLayout = (RelativeLayout)getLayoutInflater().inflate(R.layout.page_number, null);

			int height = (int) ((isNormalSize()? ThumbnailSeekBarLayout.NORMAL_HEIGHT: ThumbnailSeekBarLayout.LARGE_HEIGHT) * getResources().getDisplayMetrics().density); // サムネイルバーの高さ
			mLThumViewSize = (int) (200 * (float)height / ThumbnailSeekBarLayout.LARGE_HEIGHT); // 大サムネイル表示領域の設定
			mSeekBarLayout = new ThumbnailSeekBarLayout(this, mFoxitPdfCore, getContentId(), mAllPageCount, isLandscapeView, mDisplaySize.width, mDisplaySize.height, isNormalSize(), mPageNumberLayout);
			mSeekBarLayout.setId(id.seekbar_layout_id); // 番号は適当
			mSeekBarLayout.setVisibility(View.INVISIBLE);
			mSeekBarLayout.setFitsSystemWindows(true);
			RelativeLayout.LayoutParams param2 = createParam(ViewGroup.LayoutParams.MATCH_PARENT, height);
			param2.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
			mMainLayout.addView(mSeekBarLayout, param2);
			mMainLayout.setFitsSystemWindows(true);

			mPageNumberLayout.setVisibility(View.INVISIBLE);
			RelativeLayout.LayoutParams param = createParam(ViewGroup.LayoutParams.MATCH_PARENT, (int)(convertDensitySize(50) + 0.5f));
			param.setMargins(0, 0, 0, 10);
			param.addRule(RelativeLayout.ABOVE, mSeekBarLayout.getId());
			mMainLayout.addView(mPageNumberLayout, param);
		}


		setContentView(mMainLayout);

		// 最初に表示するページ+αをセットする
		addFirstPages();

		// 遠隔連動設定
		initRemoteLayout();
		if (isCursorModeEnable()) {
			slide.setChecked(true); // 初期状態ではカーソルオフにする。
		}
		configureRemote();

		// マーキング引継ぎ
		if (isMarking) {
			isMarking = false;
			showMarkingLayout();
		}

		if (pageBgmFlg) {
			playPageBGMSound(mCurrentPageNumber);
		}

		if (mPdfImageProvider != null) {
			mPdfImageProvider.setPauseTask(false);
		}
	}

	private void configureSize() {
		// 画面のサイズを指定
		setDisplaySize();

		// 画面スワイプ時の移動判定サイズ
		mMinDistance = mDisplaySize.width / 3;
	}

	/**
	 * 遠隔連動の状態に応じて、ツールバーや機能制限等の設定を行う
	 *
	 */
	@Override
	public void configureRemote() {
		configureCursorMode(); // いったん一律設定する
		if (meetingManager.isConnected()) {
			if (meetingManager.isSubscribed()) { // 参加者
				if (meetingManager.isPaused()) { // 休止中
					unlimitViewer();
					mPageScrollView.setFixFlag(false); // スワイプ可能にする
					mMainLayout.setRemoteDraw(false);
				} else {
					limitViewer();
					slide.setVisibility(View.INVISIBLE); // 受信者の時はカーソル設定を表示しない
					mPageScrollView.setFixFlag(true);
				}
				mBtnRemoteStart.setVisibility(View.VISIBLE);
				mExitBtn.setVisibility(View.INVISIBLE);
				mHistoryBtn.setVisibility(View.GONE); // 履歴は表示しない
			} else { // 司会者
				unlimitViewer();
				if (isCursorModeEnable()) { // 初期状態では司会者はカーソルオフにする
					slide.setChecked(true);
				}
				switchMeetingExitButton();
				mPageScrollView.setFixFlag(false);
			}
		} else { // 会議室に参加していない場合
			unlimitViewer();
		}
	}

	private void configureCursorMode() {
//		if (isCursorModeEnable()) {
//			slide.setVisibility(View.VISIBLE);
//			mPageScrollView.setFixFlag(!slide.isChecked());
//		}
//		else {
//			slide.setVisibility(View.GONE);
//		}
	}

	private void limitViewer() {
		mToolBar.setVisibility(View.INVISIBLE);
		overlapLayout.setVisibility(View.VISIBLE);
		if (mSeekBarLayout != null) {
			mSeekBarLayout.setVisibility(View.INVISIBLE);
		}
	}

	private void unlimitViewer() {
		overlapLayout.setVisibility(View.GONE);
		mExitBtn.setVisibility(View.VISIBLE);
	}

	private void initRemoteLayout() {
		overlapLayout = new RelativeLayout(this);
		RelativeLayout.LayoutParams param = createParam(FP, FP);

		subscriberToolBar = getLayoutInflater().inflate(R.layout.content_view_remote_toolbar, null);
		subscriberToolBar.setVisibility(View.GONE);
		overlapLayout.addView(subscriberToolBar, createParam(FP, WC));

		overlapLayout.setOnTouchListener(new OnTouchListener() {
			private long prevTime;

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				Logger.v(TAG, "overlap onTouch");
				if (System.currentTimeMillis() - prevTime < 300) {
					return true;
				}
				prevTime = System.currentTimeMillis();

				TranslateAnimation toolBarAnimation;
				if (subscriberToolBar.getVisibility() == View.GONE) {
					subscriberToolBar.setVisibility(View.VISIBLE);
					toolBarAnimation = new TranslateAnimation(0, 0, -subscriberToolBar.getHeight(), 0);
					Logger.d(TAG, "[singleTapMotion]:[subscriberToolBar]:VISIBLE");
					if (!meetingManager.isSubscribed() && (hasMultiPages && mPageNumberLayout != null)) {
						mPageNumberLayout.setVisibility(View.VISIBLE);
					}
				} else {
					subscriberToolBar.setVisibility(View.GONE);
					Logger.d(TAG, "[singleTapMotion]:[subscriberToolBar]:GONE");
					toolBarAnimation = new TranslateAnimation(0, 0, 0, -subscriberToolBar.getHeight());
					if (mSeekBarLayout != null) {
						mSeekBarLayout.setVisibility(View.INVISIBLE);
					}
					if (mPageNumberLayout != null) {
						mPageNumberLayout.setVisibility(View.INVISIBLE);
					}
				}
				toolBarAnimation.setDuration(500);
				return true;
			}
		});
		mMainLayout.addView(overlapLayout, param);

		TextView titleTxt = (TextView) subscriberToolBar.findViewById(R.id.txt_content_title);
		titleTxt.setText("");

		ImageButton exitBtn = (ImageButton) subscriberToolBar.findViewById(R.id.btn_exit);
		exitBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.v(TAG, "exit onClick");
				showMeetingExitDialog();
			}
		});

		// 会議室設定(参加者)
		ImageButton meetingRoomSettingBtn = (ImageButton) subscriberToolBar.findViewById(R.id.btn_meetingroom_setting);
		meetingRoomSettingBtn.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.v(TAG, "meetingRoomSettingBtn onClick");

				mShowedPopupWindow = new ABVPopupListWindow(GuideViewActivity.this, R.layout.popup_meetingroom_setting);
				mShowedPopupWindow.setWidth(getRDimensionSize(R.dimen.popup_size_xlarge));

				// 司会者マーキング共有設定(参加者モード場合は非表示)
				CheckedTextView markingShareCheck = (CheckedTextView) mShowedPopupWindow.findViewById(R.id.checkedMarkingShare);
				markingShareCheck.setVisibility(View.GONE);

				// 会議室マーキング自動保存
				CheckedTextView markingAutoSaveCheck = (CheckedTextView) mShowedPopupWindow.findViewById(R.id.checkedMarkingAutoSave);

				boolean meetingMarkingAutoSaveFlag = PreferenceUtil.get(GuideViewActivity.this, AppDefType.UserPrefKey.MEETING_MARKING_AUTO_SAVE, false);
				markingAutoSaveCheck.setChecked(meetingMarkingAutoSaveFlag);
				markingAutoSaveCheck.setOnClickListener(new OnClickListener() {
					@Override
					public void onClick(View v) {
						CheckedTextView checkedTV = (CheckedTextView) v;
						boolean checkFlag = !checkedTV.isChecked();// 反対の値をセット
						checkedTV.setChecked(checkFlag);
						put(AppDefType.UserPrefKey.MEETING_MARKING_AUTO_SAVE, checkFlag);
					}
				});

				// 設定ポップアップ表示
				mShowedPopupWindow.showAsDropDown(v);
			}
		});

		meetingRoomSettingBtn.setVisibility(View.GONE);

		ImageButton promoteBtn = (ImageButton) subscriberToolBar.findViewById(R.id.btn_promote);
		promoteBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.v(TAG, "promote onClick");
				sendPromoteRequest();
				subscriberToolBar.setVisibility(View.GONE);
			}
		});

		final ImageButton pauseBtn = (ImageButton) subscriberToolBar.findViewById(R.id.btn_remote_pause);
		pauseBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.v(TAG, "remoteOnOff onClick");
				meetingManager.setPaused(true);
				configureRemote();

				if (isMarking) {
					closeMarkingLayout();
				} else {
					for (MarkingView markingView : mMarkingViewList) {
						markingView.reLoad();
					}
				}
			}
		});
	}

	private boolean addPageViewFinish;
	private boolean smoothScrollToFinish;

	private void addFirstPages() {
		// 最初の2ページをレンダリングする
		touchFlg = true;
		addPageViewFinish = false;
		smoothScrollToFinish = false;

		Intent it = getIntent();
		int jumpPage = it.getIntExtra("page", -1);
		it.removeExtra("page");

		if (mCurrentPageNumber != 0) {
			jumpPage = mCurrentPageNumber;
		}
		else if (jumpPage >= mAllPageCount) { // jumpPageが最終ページを超える場合、最終ページにする。
			jumpPage = mAllPageCount - 1;
		}
		else if (jumpPage < 0) {
			jumpPage = 0;
		}


			if (mPdfImageProvider == null) {
				mPdfImageProvider = new PdfImageProvider(mFoxitPdfCore);
			}
			else {
				mPdfImageProvider.cancelAll(false); // 回転した場合いったんキャンセルする
			}

			if (hasMultiPages) {
				mSeekBarLayout.setPdfImageProvider(mPdfImageProvider);
			}
			mPdfImageProvider.setPauseTask(true);
			mPdfImageProvider.createImage(contentId, jumpPage, mDisplaySize);

		Logger.d(TAG, "jumpPage=" + jumpPage);
		mCurrentPageNumber = jumpPage;
		addPageView(mCurrentPageNumber);
		new Handler().postDelayed(new Runnable() {
			@Override
			public void run() {
				if (mAllPageCount > mCurrentPageNumber + 1) {
					addPageView(mCurrentPageNumber + 1);
				}
				if (mCurrentPageNumber > 0) {
					addPageView(mCurrentPageNumber - 1);
				}

				addPageViewFinish = true;
				if (smoothScrollToFinish) {
					touchFlg = false;
				}
			}
		}, 500);
		mPageScrollView.post(new Runnable() {
			@Override
			public void run() {
				mPageScrollView.smoothScrollTo(mCurrentPageNumber*mDisplaySize.width, 0);

				smoothScrollToFinish = true;
				if (addPageViewFinish) {
					touchFlg = false;
				}
			}
		});
	}

	private void put(String key, boolean val) {
		pref.edit().putBoolean(key, val).commit();
	}

	/**
	 * ツールバーを生成する
	 */
	private void createToolBar() {
		mToolBar = getLayoutInflater().inflate(R.layout.guid_view_toolbar, null);
		mToolBar.setVisibility(View.GONE);
		mExitBtn = (Button) mToolBar.findViewById(R.id.btn_exit);
		mExitBtn.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Logger.d(TAG, "[exit] click!!");
				exitActivity();
			}
		});
		TextView titleTextView = (TextView)mToolBar.findViewById(id.tv_guide_title);
		// リソースパターンの適用
		titleTextView.setText(PatternStringUtil.patternToString(getApplicationContext(),
								R.string.operation_manual,
								getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
		//RelativeLayout.LayoutParams param1 = createParam(ViewGroup.LayoutParams.MATCH_PARENT, (int)(48 * tmpDensity + 0.5f));
		RelativeLayout.LayoutParams param1 = createParam(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);

		param1.addRule(RelativeLayout.ALIGN_PARENT_TOP);
		mMainLayout.addView(mToolBar, param1);
	}

	private void setMarkingViewVisibility(boolean visible){
		for (MarkingView markingView : mMarkingViewList) {
			if (visible) {
				markingView.setVisibility(View.VISIBLE);
			} else {
				markingView.setVisibility(View.GONE);
			}
		}

		if (meetingManager.isSendable()) {
			JSONObject json = new JSONObject();
			if (visible) {
				json.put(MeetingManager.MARKING_ACTION, MeetingManager.MARKING_ACTION_VISIBLE);
			} else {
				json.put(MeetingManager.MARKING_ACTION, MeetingManager.MARKING_ACTION_INVISIBLE);
			}

			meetingManager.sendWs(MeetingManager.CMD_MARKING, contentId, mCurrentPageNumber, null, json);
		}
	}

	/**
	 * ThumbnailSeekBarから表示する大サムネイルを生成する
	 *  枠と突起物の描画のキャッシュ（BitmapとCanvas）
	 *
	 * @param page
	 * @param left
	 * @param top
	 * @param stickCenter 突起物x座標
	 * @param pageNumHSize ページ番号表示用height
	 * @param thumb サムネイルデータ
	 */
	public void createLargeThumView(int page, int left, int top, int stickCenter, int pageNumHSize, Drawable thumb) {
		// 枠を生成する。
		Bitmap bitmap = Bitmap.createBitmap(mLThumViewSize, mLThumViewSize + pageNumHSize + THUMB_STICK_SIZE, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);
		Paint paint = new Paint();
		int LARGE_HIGHLIGHT_COLOR = 0xD025120C;
		paint.setColor(LARGE_HIGHLIGHT_COLOR);
		paint.setAntiAlias(true);
		canvas.drawRoundRect(new RectF(0, 0, mLThumViewSize, mLThumViewSize + pageNumHSize), 10, 10, paint);

		// 突起物を表示する
		Path drawPath = new Path();
		drawPath.moveTo(stickCenter - THUMB_STICK_SIZE, mLThumViewSize + pageNumHSize);
		drawPath.lineTo(stickCenter, mLThumViewSize + pageNumHSize + THUMB_STICK_SIZE);
		drawPath.lineTo(stickCenter + THUMB_STICK_SIZE, mLThumViewSize + pageNumHSize);
		drawPath.close();
		canvas.drawPath(drawPath,paint);

		// ページ番号の表示
		Paint paintText = new Paint();
		paintText.setColor(Color.WHITE);
		paintText.setTextSize(15f);
		String pageText = "Page " + (page + 1);
		canvas.drawText(pageText, mLThumViewSize / 2 - pageText.length() * 4, mLThumViewSize + pageNumHSize / 2 - (isLandscapeView?13:0), paintText);

		// サムネイルの描画
		thumb.draw(canvas);

		mLargeImageView = new ImageView(this);
		mLargeImageView.setImageBitmap(bitmap);

		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mLThumViewSize, mLThumViewSize + pageNumHSize + THUMB_STICK_SIZE);
		params.setMargins(left, top, 0, 0);

		mMainLayout.addView(mLargeImageView, params);
	}

	public void removeLargeThumView() {
		if (mLargeImageView != null) {
			mLargeImageView.setImageDrawable(null);
			mMainLayout.removeView(mLargeImageView);
			mLargeImageView = null;
		}
	}

	private void allReset() {
		stopSound();
		stopVideo();
		getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
	}

	private RelativeLayout.LayoutParams createParam(int w, int h) {
		return new RelativeLayout.LayoutParams(w, h);
	}

	/**
	 * SimpleOnGestureListener
	 **/
	private SimpleOnGestureListener mGestureListener = new SimpleOnGestureListener() {
		@Override
		public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
			if (System.currentTimeMillis() - mFromOverEventPointTime < 700) { // 0.7秒
				return false;
			}

			if (mPageScrollView.isZooming() == false && !isEnqueteOpening) {
				stopVideo();
			}

			if (isEnquete && isEnqueteFullScreen) {
				return false;
			} else if (isDisallowMovePage) {
				isDisallowMovePage = true;
			} else if (isSeeking == false) {
				Logger.v(TAG, "[SimpleOnGestureListener]:[onFling]");
				if (e1 != null && e2 != null) {
					scrollToPage(e1.getX(), e2.getX());
				}
				mScrollStatus = ScrollStatus.FLING;
				mFromOverEventPointTime = System.currentTimeMillis();
				return true;
			} else {
				isSeeking = false;
			}
			return false;
		}

		@Override
		public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

			if (mSeekBarLayout != null && mSeekBarLayout.isSeeking()) {
				return false;
			}

			if (isEnquete && isEnqueteFullScreen) {
				return false;
			} else if (isDisallowMovePage) {
				isDisallowMovePage = false;
			} else if (isSeeking) {
				isSeeking = false;
			} else{
				if (mPageScrollView.isZooming() == false && !isEnqueteOpening) {
					stopVideo();
				}

				if (e1 != null && e2 != null) {
					mScrollDistance = e1.getX() - e2.getX();
				}
				mScrollStatus = ScrollStatus.SCROLL;
				Logger.d(TAG, "[SimpleOnGestureListener]:[onScroll]:mScrollDistance=" + mScrollDistance);
				// ページ遷移の判定はdispatchTouchEventで行う
			}
			return super.onScroll(e1, e2, distanceX, distanceY);
		}
	};

	//2012 12 17 Contents link by jeonghun
	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			Logger.d(TAG, "KeyEvent.KEYCODE_BACK");

			if (isVideoMax) {
				videoMaxToDefault();
			} else if (isMarking) {
				mMarkingLayout.showSaveDialog();
			} else if (isEnquete) {
				enqueteLayout.showEnqueteDialog(); //앙케이트 중 뒤로가기 버튼을 누를시 Alert 표시
			} else if (fullVideoView != null) {
				fullVideoView.close();
				fullVideoView = null;
			} else {
				if (meetingManager.isSubscribed()) { // 参加者の場合pause状態にする。
					showMeetingExitDialog();
					return false;
				}

				allReset();

				mActivityFinishFlg = true;
				moveToBack();
			}
			return false;
		}
		return super.onKeyUp(keyCode, event);
	}

	@Override
	protected void onStop() {
		// ページ別ログ
		if (!DeviceInfo.isForegrdound(getApplicationContext())) {
			ContentLogUtil.getInstance().pauseContentPageReadLog(contentId, mCurrentPageNumber, readingLogId);
		}

		super.onStop();
		Logger.d(TAG, "onStop");
	}

	@Override
	protected void onDestroy() {
		Logger.d(TAG, "onDestroy");
		stopSound();
		stopVideo();

		if (fullVideoView != null) {
			fullVideoView.close();
			fullVideoView = null;
		}
		objectIdButtonMap.clear();
		objectIdPopupMap.clear();

		// ページ別ログ
		ContentLogUtil.getInstance().endContentPageReadLog(contentId, mCurrentPageNumber, readingLogId);


		super.onDestroy();
		removeViews();

		ABVViewUnbindHelper.unbindReferences(mMainLayout);
		getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

		if (mPdfImageProvider != null) {
			mPdfImageProvider.cancelAll(true);
		}
	}

	private void removeViews() {
		try{
			if (mContentWrapLayout != null) {
				int childCount = mContentWrapLayout.getChildCount();
				for (int i=childCount-1; i>= 0; i--) {
					View child = mContentWrapLayout.getChildAt(i);
					if (child instanceof RelativeLayout) {
						RelativeLayout pageLayout = (RelativeLayout) child;
						Logger.v(TAG, "memory:[removePage]:pageNumber=%s, instance=%s", pageLayout.getId(), pageLayout);
						for (int j=0; j < pageLayout.getChildCount(); j++) {
							if (pageLayout.getChildAt(j) instanceof PDFPageView) {
								PDFPageView ppv =(PDFPageView) pageLayout.getChildAt(j);
								ppv.releaseResources();
								break;
							}
						}
						pageLayout.removeAllViews();
						mContentWrapLayout.removeView(pageLayout);
					}
				}
			}
		}catch(Exception e) {
			Logger.e(TAG, "removeViews failed.", e);
			ABVToastUtil.showMakeText(getApplicationContext(), R.string.ERROR, Toast.LENGTH_SHORT);
		}

		if (mSeekBarLayout != null) {
			mSeekBarLayout.destroy();
		}
	}

	@Override
	public boolean dispatchTouchEvent(MotionEvent ev) {
		try {
			if (touchFlg) {
				return false;
			}
			Logger.d(TAG, "[dispatchTouchEvent]:start");

			if (mPdfImageProvider != null) {
				mPdfImageProvider.setPauseTask(true);
			}

			Logger.d(TAG, "isVideoMax" + isVideoMax);
			mMainLayout.drawCursor(ev.getAction(), ev.getX(), ev.getY());

			try {
				// この処理は要る？？
				super.dispatchTouchEvent(ev);
			} catch (IllegalArgumentException e) {
				if (e.getMessage() != null && e.getMessage().contains("pointerIndex out of range")) {
					Logger.w(TAG, "[dispatchTouchEvent] event" + ev.toString() + " Exception=" + e.toString()); // 無視する
				}
				else {
					throw e;
				}
			}

			if (isMarking || isVideoMax) {
				return true;
			}

			int action = ev.getAction() & MotionEvent.ACTION_MASK;
			if (action == MotionEvent.ACTION_POINTER_UP) {
				Logger.d(TAG, "[dispatchTouchEvent]:action=" + action);
				mFromOverEventPointTime = System.currentTimeMillis();
			}
			boolean result = mActivityGestureDetector.onTouchEvent(ev);

			//		Logger.d(TAG, "[dispatchTouchEvent]:action=" + action + ", count=" + ev.getPointerCount());
			if (action == MotionEvent.ACTION_UP && mScrollStatus == ScrollStatus.SCROLL && mPageScrollView.isScrollable()) {
				// Scroll時のページ遷移の判定を行う
				if (Math.abs(mScrollDistance) > mMinDistance) {
					Logger.d(TAG, "mScrollDistance=%s, mMinDistance=%s", mScrollDistance, mMinDistance);
					scrollToPage((int)mScrollDistance);
				} else {
					// back current position
					Logger.d(TAG, "smoothScrollTo");
					mPageScrollView.smoothScrollTo(mCurrentPageNumber*mDisplaySize.width, 0);
				}
			}
			Logger.d(TAG, "[dispatchTouchEvent]:end:result=" + result);
			return result;
		} catch (Exception e) {
			// Point Error 対応
			Logger.e(TAG, "[dispatchTouchEvent]:e=" + e.getMessage(), e);
			ABVToastUtil.showMakeText(getApplicationContext(), R.string.ERROR, Toast.LENGTH_SHORT);
			return false;
		}
		finally {
			if (mPdfImageProvider != null) {
				mPdfImageProvider.setPauseTask(false);
			}
		}
	}

	/**
	 * TODO: later ツールバーに限らないので名前変更
	 *
	 * @param isVisible true:View.VISIBLE, false:View.GONE
	 */
	public void setToolbarVisable(boolean isVisible) {
		Logger.d(TAG, "[setToolbarVisable]:isVisable=" + isVisible);

		if (!meetingManager.isSubscribed() || meetingManager.isPaused()) {
			setBarVisible(isVisible);
		}
		if (isVisible) {
			if (hasMultiPages) {
				mSeekBarLayout.createThumbnail();
				mSeekBarLayout.showMidThum(mCurrentPageNumber);
			}

			// マーキングが存在しない場合、アイコンを表示しない
			for (MarkingView markingView : mMarkingViewList) {
				if (markingView.getPageNum() == mCurrentPageNumber) {
					if (markingView.isMarkingExist()) {
						tbtnMarking.setVisibility(View.VISIBLE);
					} else {
						tbtnMarking.setVisibility(View.GONE);
					}
				}
			}

			if (hasMultiPages) {
				// ページ番号を表示する
				setCurrentPageNumber();
			}
		}
		else {
			if (hasMultiPages) {
				// サムネイルバーの大・中イメージを削除する
				removeLargeThumView();
				mSeekBarLayout.clearImageView();
			}
		}

		setMeetingParticipantCount(isVisible, mToolBar);
	}

	/**
	 * ツールバー・サムネイルバー・ページ番号の表示切替
	 *
	 * @param isVisable
	 */
	public void setBarVisible(boolean isVisable) {
		int visibility = isVisable ? View.VISIBLE : View.GONE;
		mToolBar.setVisibility(visibility);
		if (hasMultiPages) {
			visibility = isVisable ? View.VISIBLE : View.INVISIBLE;
			mSeekBarLayout.setVisibility(visibility);
			mPageNumberLayout.setVisibility(visibility);
		}
	}

	private void setCurrentPageNumber() {
		if (mPageNumberLayout != null) {
			TextView pageNumberTextView = (TextView)mPageNumberLayout.findViewById(id.txt_page_number);
			//noinspection deprecation(API16から非推奨になった。無視)
			pageNumberTextView.setBackgroundDrawable(getRDrawable(R.drawable.rounded_edittext));
			pageNumberTextView.setText((mCurrentPageNumber + 1) + " / " + mAllPageCount);
		}
	}

	/**
	 * called from ZoomRelativeLayout
	 */
	public void singleTapMotion() {
		if (isEnquete) {
			return;
		}

		Logger.d(TAG, "[singleTapMotion]:isOnClick=false");
		if (mPageScrollView.isZooming()) {
			ZoomRelativeLayout zoomRelativeLayout = mShowPageLayout.get(mCurrentPageNumber);
			if (zoomRelativeLayout == null) {
				Logger.e(TAG, "zoomRelativeLayout is null");
				return;
			}
			// 拡大中は拡大率を表示
			int scale = (int) (mShowPageLayout.get(mCurrentPageNumber).getScaleFactor() * 100f);
			Toast.makeText(getApplicationContext(), String.format("%d%%", scale), Toast.LENGTH_SHORT).show();
		} else {
			TranslateAnimation toolBarAnimation;
			if (mToolBar.getVisibility() == View.GONE) {
				setToolbarVisable(true);
				toolBarAnimation = new TranslateAnimation(0, 0, -mToolBar.getHeight(), 0);
				Logger.d(TAG, "[singleTapMotion]:[mToolBar]:VISIBLE");
			} else {
				setToolbarVisable(false);
				Logger.d(TAG, "[singleTapMotion]:[mToolBar]:GONE");
				toolBarAnimation = new TranslateAnimation(0, 0, 0, -mToolBar.getHeight());
			}
			toolBarAnimation.setDuration(500);

			if (hasMultiPages) {
				TranslateAnimation seekBarAnimation;
				if (mToolBar.getVisibility() == View.GONE) {
					seekBarAnimation = new TranslateAnimation(0, mDisplaySize.height, mDisplaySize.height - mSeekBarLayout.getHeight(), 0);
				} else {
					seekBarAnimation = new TranslateAnimation(0, mDisplaySize.height - mSeekBarLayout.getHeight(), mDisplaySize.height, 0);
				}
				seekBarAnimation.setDuration(500);
			}
		}
	}

	// #################################################################################################### //
	// page controll
	// #################################################################################################### //

	/**
	 * ページを追加する
	 * @param pageNumber
	 */
	private void addPageView(int pageNumber) {

		if (pageNumber < 0 || pageNumber >= mAllPageCount) {
			return;
		}

		Logger.v(TAG, "[addPageView]start:page=%s", pageNumber);

		long totalBitmapSize = calcImageSize(pageNumber) + mDisplaySize.width * mDisplaySize.height * 4 * 2; // イメージボタンとPDFの合計サイズ

		RelativeLayout pageLayout = new RelativeLayout(this) {
			@Override
			public void removeView(View view) {
				if (view instanceof PDFPageView) {
					Logger.v(TAG, "pageLayout.removeView");
				}
				super.removeView(view);
			}
		};

		final int pageNum = pageNumber;
		mPageActionList.add(new PageActionList(pageNumber));

		pageLayout.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {

			@Override
			public void onChildViewRemoved(View parent, View child) {
				if (child instanceof PDFPageView) {
					Logger.v(TAG, "pageLayout.onChildViewRemoved:PDFPageView:%s", pageNum);
					((PDFPageView) child).releaseResources();
				} else if (child instanceof ViewGroup) {
					Logger.v(TAG, "pageLayout.onChildViewRemoved:ViewGroup:%s", pageNum);
					((ViewGroup) child).removeAllViews();
				}
			}

			@Override
			public void onChildViewAdded(View parent, View child) {
			}
		});

		pageLayout.setId(pageNumber);
		RelativeLayout.LayoutParams point = new RelativeLayout.LayoutParams(mDisplaySize.width, R_FP);
		point.setMargins(pageNumber * mDisplaySize.width, 0, 0, 0);
		mContentWrapLayout.addView(pageLayout, point);

		Size pageSize = null;
		PageView pageView;
		try {
			pageSize = new Size(mFoxitPdfCore.getPageSize(pageNumber));
		} catch (PDFException e) {
			//TODO エラーの場合、画面制御必要
			Logger.e(TAG, "getPageSize fail", e);
		}
		if(pageSize == null) {
			return;
		}
		pageView = new PDFPageView(this, mFoxitPdfCore, mPdfImageProvider, pageSize, pageNumber, mDisplaySize, pageLayout, contentId);
		((PDFPageView) pageView).setPage();

		pageLayout.addView(pageView, mDisplaySize.width, mDisplaySize.height);

		final ZoomRelativeLayout zoomLayout = new ZoomRelativeLayout(this);
		zoomLayout.setPageSize(pageSize);
		zoomLayout.setPageNumber(pageNumber);
		zoomLayout.setContentDto(mContentDto);
		zoomLayout.setPageMargin(mDisplaySize.width, mDisplaySize.height);
		zoomLayout.setPageScrollView(mPageScrollView);
		PDFAuthoringSize authoringSize = new PDFAuthoringSize(pageSize);
		zoomLayout.setAuthoringScale(Math.min((float) mDisplaySize.width / authoringSize.width, (float) mDisplaySize.height / authoringSize.height));
		zoomLayout.setUnAuthorizedContentListener(unAuthorizedContentListener);

		if (mPageInfoJSON != null) {
			final PageInfoJSONData data = mPageInfoJSON.getPageData(pageNumber);
			zoomLayout.setAuthoringPageSize(data.pageWidth, data.pageHeight);
		} else {
			// PDFなしバージョン
			zoomLayout.setAuthoringPageSize(mBaseFileSize.width, mBaseFileSize.height);
		}

		zoomLayout.setVisibility(View.GONE);

		RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(mDisplaySize.width, mDisplaySize.height);
		params.addRule(RelativeLayout.CENTER_IN_PARENT);
		pageLayout.addView(zoomLayout, params);
		mShowPageLayout.put(pageNum, zoomLayout);
		Logger.v(TAG, "[addPageView]end:page=%s", pageNumber);
	}

	private long calcImageSize(int pageNumber) {
		if (mContentJSON == null) {
			return 0;
		}
		JSONArray objects = mContentJSON.getPageObject(pageNumber);
		if (objects == null) {
			return 0;
		}

		ArrayList<String> pathList = new ArrayList<>();
		for (int i = 0; i < objects.length(); i++) {
			JSONObject pageObject = objects.getJSONObject(i);
			try {
				pathList.add(mContentDir + "/" + pageObject.getJSONObject("mediaInfo").getString("fileName"));
			} catch (JSONException e) {
				// ignore
			}
		}

		return BitmapUtil.getTotalBitmapSize(pathList, Config.ARGB_8888);

	}

	/**
	 * ページスクロールを行う
	 * @param direct 0より大き：右へ、0より小さい：左へ
	 */
	private void scrollToPage(int direct) {
		Logger.v(TAG, "[scrollToPage]:direct=%s isScrollable=%s", direct, mPageScrollView.isScrollable());
		if (mPageScrollView.isScrollable()) {
			stopVideo();
			setToolbarVisable(false);
			if (direct < 0) {
				// move left
				moveTo(-1);
				Logger.v(TAG, "[scrollToPage]:left=%s", mCurrentPageNumber);
			} else {
				// move right
				moveTo(1);
				Logger.v(TAG, "[scrollToPage]:right=%s", mCurrentPageNumber);
			}
			playPageBGMSound(mCurrentPageNumber);
		}
	}

	/**
	 * ページをスクロールさせる
	 * @param x1 Start Point
	 * @param x2 End Point
	 */
	private void scrollToPage(float x1, float x2) {
		scrollToPage((int)(x1 - x2));
	}

	/**
	 * 左/右側へ移動しながらページの追加、削除を行う
	 */
	private void moveTo(final int count) {

		Logger.d(TAG, "mCurrentPageNumber" + mCurrentPageNumber);

		final int currentPageNumber = mCurrentPageNumber;
		final int nextPageNumber = mCurrentPageNumber + count;
		if (nextPageNumber >= 0 && nextPageNumber < mAllPageCount) {
			mCurrentPageNumber = nextPageNumber;

			// ページ別ログ
			ContentLogUtil.getInstance().contentPageMove(contentId, readingLogId, currentPageNumber, nextPageNumber);

			if (contentsBgmFlg && !StringUtil.isNullOrEmpty(contentsBgmFilePath) && !contentBGMPlayer.isPlaying()) {
				//contentsBgmFilePath
				contentBGMPlayer = new ABVMediaPlayer(true);
				try {
					Logger.v(TAG, "[addMusic]:MediaPlayer Content BGM");
					contentBGMPlayer.setDataSource(contentsBgmFilePath);
					contentBGMPlayer.prepare();
					contentBGMPlayer.start();
				} catch (IOException e) {
					Logger.e(TAG, "Can't play content BGM",e);
					ABVToastUtil.showMakeText(getApplicationContext(), R.string.ERROR, Toast.LENGTH_SHORT);
				}
			}

			//リモート機能
			if (meetingManager.isSendable()) { // TODO: later 止まったタイミングで送るように要修正
				// マーキングモード終了を通知
				JSONObject json = new JSONObject();
				json.put(MeetingManager.MARKING_ACTION, MeetingManager.MARKING_ACTION_END);
				meetingManager.sendWs(MeetingManager.CMD_MARKING, getContentId(), currentPageNumber, null, json);

				// ページ移動
				meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, getContentId(), nextPageNumber, null, null);
			}

			new Handler().postDelayed(new Runnable() {
				@Override
				public void run() {
					removePage(currentPageNumber - count);// 前のページを削除
				}
			}, intervalAddOrRemovePage);

			new Handler().postDelayed(new Runnable() {
				@Override
				public void run() {
					addPageView(nextPageNumber + count); // 先のページを追加
				}
			}, intervalAddOrRemovePage);

			mPageScrollView.post(new Runnable() {
				@Override
				public void run() {
					mPageScrollView.smoothScrollTo(nextPageNumber * mDisplaySize.width, 0);
				}
			});

			//jeonghun SeekBar Bug Fixed
			setCurrentPageNumber();
			//jeonghun moveTo playPageBGM Bug Fixed
			playPageBGMSound(nextPageNumber);

			//탭사운드 플레이 Bug
			playTapSoundFlg = false;

			//좌우 버튼 이동시 툴바 갱신 버그 수정
			if (moveBtnFlg) {
				stopVideo();
				setToolbarVisable(true);
				setToolbarVisable(false);
				moveBtnFlg = false;
			}

			Logger.d(TAG, "[moveTo]:show page=" + nextPageNumber);
		} else {
			Logger.d(TAG, "### pass move to");
		}
	}


	/**
	 * 指定番号のページを削除する
	 * @param pageNumber 0から始まるページ番号
	 */
	private void removePage(int pageNumber) {
		Logger.i(TAG, "removePage: " + pageNumber);
		if (pageNumber < 0 || pageNumber >= mAllPageCount) {
			return;
		}

		int pcaIndex = getPageContentArrayIndex(pageNumber);
		if (pcaIndex >= 0) {
			if (mPageActionList.get(pcaIndex).arrayVideoMount != null) {
				for (int i = 0; i < mPageActionList.get(pcaIndex).arrayVideoMount.size(); i++) {
					mPageActionList.get(pcaIndex).arrayVideoMount.get(i).stopVideo();
				}
			}
			if (mPageActionList.get(pcaIndex).arrayVideoChange != null) {
				for (int i = 0; i < mPageActionList.get(pcaIndex).arrayVideoChange.size(); i++) {
					mPageActionList.get(pcaIndex).arrayVideoChange.get(i).stopVideo();
				}
			}
			mPageActionList.get(pcaIndex).clear();
			mPageActionList.remove(pcaIndex);
		}

		for (int i = 0; i < mMarkingViewList.size(); i++) {
			if (mMarkingViewList.get(i).getPageNum() == pageNumber) {
				mMarkingViewList.remove(i);
				break;
			}
		}

		for (int i = 0; i < mContentWrapLayout.getChildCount(); i++) {
			if (mContentWrapLayout.getChildAt(i) instanceof RelativeLayout) {
				RelativeLayout child = (RelativeLayout) mContentWrapLayout.getChildAt(i);
				if (child.getId() == pageNumber) {
					Logger.v(TAG, "memory:[removePage]:pageNumber=%s, instance=%s", child.getId(), child);
					RelativeLayout pageLayout = child;

					for (int j=0; j < pageLayout.getChildCount(); j++) {
						if (pageLayout.getChildAt(j) instanceof PDFPageView) {
							PDFPageView ppv =(PDFPageView) pageLayout.getChildAt(j);
							ppv.releaseResources();
						}
					}

					pageLayout.removeAllViews();
					mContentWrapLayout.removeView(child);
					break;
				}
			}
		}

		mShowPageLayout.remove(pageNumber);

	}

	/**
	 * 画面が表示されてから呼ぶ
	 *
	 * TODO: moveToとロジック重複
	 *
	 * @param jumpPage
	 */
	public void jumpToPage(final int jumpPage) {
		stopVideo();
		// ページ別ログ
		ContentLogUtil.getInstance().contentPageMove(contentId, readingLogId, mCurrentPageNumber, jumpPage);

		Logger.i(TAG, "[jumpToPage]:start=" + jumpPage + ", childCount=" + mContentWrapLayout.getChildCount());
		if (jumpPage == mCurrentPageNumber || touchFlg) {
			return;
		}
		touchFlg =true;

		if (mPdfImageProvider != null) {
			mPdfImageProvider.cancelAll(true);
			Size displaySize = mDisplaySize;
			mPdfImageProvider.createImage(contentId, jumpPage, displaySize);
		}

		addOrRemovePages(jumpPage);

		mPageScrollView.setZoomingFlag(false);
		mPageScrollView.post(new Runnable() {
			@Override
			public void run() {
				mPageScrollView.smoothScrollTo(mCurrentPageNumber*mDisplaySize.width, 0);
				touchFlg = false;
			}
		});

		if (mToolBar.getVisibility() == View.VISIBLE && mSeekBarLayout != null && mSeekBarLayout.getVisibility() == View.VISIBLE) {
			//ツールバーが可視の時は内容更新
			setToolbarVisable(true);
		}
		// BGM
		if (contentsBgmFlg && !StringUtil.isNullOrEmpty(contentsBgmFilePath) && !contentBGMPlayer.isPlaying()) {
			//contentsBgmFilePath
			contentBGMPlayer = new ABVMediaPlayer(true);
			try {
				Logger.v(TAG, "[addMusic]:MediaPlayer Content BGM");
				contentBGMPlayer.setDataSource(contentsBgmFilePath);
				contentBGMPlayer.prepare();
				contentBGMPlayer.start();
			} catch (IOException e) {
				Logger.e(TAG, "Can't play content BGM", e);
				ABVToastUtil.showMakeText(getApplicationContext(), R.string.ERROR, Toast.LENGTH_SHORT);
			}
		}
		playPageBGMSound(jumpPage);

		//탭사운드 플레이 Bug
		playTapSoundFlg = false;

		setCurrentPageNumber();

		if (meetingManager.isSendable()) { // TODO later 止まったタイミングで送るように要修正
			meetingManager.sendWs(MeetingManager.CMD_MOVEPAGE, getContentId(), jumpPage, null, null);
		}
	}

	private void addOrRemovePages(final int jumpPage) {
		final int currentPage = mCurrentPageNumber;
		mCurrentPageNumber = jumpPage;

		if (Math.abs(jumpPage - currentPage) != 1) {
			addPageView(jumpPage);
		}
		new Handler().postDelayed(new Runnable() {
			@Override
			public void run() { // ジャンプするページに応じて必要なだけ作成・削除する
				if (jumpPage - currentPage != 1 && jumpPage - currentPage != 2) {
					addPageView(jumpPage - 1);
					removePage(currentPage + 1);
				}
				if (jumpPage - currentPage != -1 && jumpPage - currentPage != -2) {
					addPageView(jumpPage + 1);
					removePage(currentPage - 1);
				}
				if (Math.abs(jumpPage - currentPage) != 1) {
					removePage(currentPage);
				}
			}
		}, 500); // あまり早くしすぎると描画前に走って描画が遅れる。
	}

	/**
	 * 再生中の動画を全停止する。
	 *
	 */
	public void stopVideo() {
		for (int i = 0; i < mPageActionList.size(); i++) {
			stopMountVideo(mPageActionList.get(i).arrayVideoMount, null, false);
			stopChangeVideo(mPageActionList.get(i).arrayVideoChange, null, false);
		}
	}

	/**
	 * 埋め込み動画を停止する
	 *
	 * @param invisibleSurfaceView surfaceViewを非表示にするか
	 * @param excludeIndex　停止しない動画index（nullを指定すればすべて）
	 */
	public void stopCurrentPageMountVideo(Integer excludeIndex, boolean invisibleSurfaceView) {
		int pageidx = getPageContentArrayIndex(mCurrentPageNumber);
		stopMountVideo(mPageActionList.get(pageidx).arrayVideoMount, excludeIndex, invisibleSurfaceView);
	}

	private void stopMountVideo(ArrayList<VideoMountAction> arrayVideoMount, Integer excludeIndex, boolean invisibleSurfaceView) {
		for (int i = 0; i < arrayVideoMount.size(); i++) {
			if (excludeIndex == null || i != excludeIndex) {
				arrayVideoMount.get(i).stopVideo();
				if (invisibleSurfaceView) {
					arrayVideoMount.get(i).setSurfaceVisibility(View.INVISIBLE);
				}
			}
		}
	}

	/**
	 * 差替え動画を停止する
	 *
	 * @param excludeIndex　停止しない動画index（nullを指定すればすべて）
	 * @param invisibleSurfaceView surfaceViewを非表示にするか
	 */
	public void stopCurrentPageChangeVideo(Integer excludeIndex, boolean invisibleSurfaceView) {
		int pageidx = getPageContentArrayIndex(mCurrentPageNumber);
		stopChangeVideo(mPageActionList.get(pageidx).arrayVideoChange, excludeIndex, invisibleSurfaceView);
	}

	private void stopChangeVideo(ArrayList<VideoMountAction> arrayVideoChange, Integer excludeIndex, boolean invisibleSurfaceView) {
		for (int i = 0; i < arrayVideoChange.size(); i++) {
			if (excludeIndex == null || i != excludeIndex) {
				arrayVideoChange.get(i).stopVideo();
				if (invisibleSurfaceView) {
					arrayVideoChange.get(i).setSurfaceVisibility(View.INVISIBLE);
				}
			}
		}
	}

	/**
	 * 自分以外のSurfaceViewをすべてVISIBLEにする。
	 *
	 * @param isMountVideo
	 * @param index
	 */
	public void setSurfaceViewVisible(boolean isMountVideo, int index) {
		int pageidx = getPageContentArrayIndex(mCurrentPageNumber);
		for (int i = 0; i < mPageActionList.size(); i++) {
			for (int j = 0; j < mPageActionList.get(i).arrayVideoMount.size(); j++) {
				if (i != pageidx || j != index || !isMountVideo) {
					mPageActionList.get(i).arrayVideoMount.get(j).setSurfaceVisibility(View.VISIBLE);
				}
			}
			for (int j = 0; j < mPageActionList.get(i).arrayVideoChange.size(); j++) {
				if (i != pageidx || j != index || isMountVideo) {
					mPageActionList.get(i).arrayVideoChange.get(j).setSurfaceVisibility(View.VISIBLE);
				}
			}
		}
	}

	/**
	 * 再生中のAudioPlayerを一時停止する
	 */
	public void stopSound() {
		if (tapPlayer != null && tapPlayer.isPlaying()) {
			tapPlayer.pause();
			tapPlayer.stop();
			Logger.v(TAG, "[stopSound]:tapPlayer");
		} else if (pageBGMPlayer != null && pageBGMPlayer.isPlaying()) {
			pageBGMPlayer.pause();
			Logger.v(TAG, "[stopSound]:pageBGMPlayer");
		} else if (contentBGMPlayer != null && contentBGMPlayer.isPlaying()) {
			contentBGMPlayer.pause();
			Logger.v(TAG, "[stopSound]:contentBGMPlayer");
		}
	}
	private void playPageBGMSound(int pageNumber) {
		String bgmFilePath = pageBGMPathList.get(pageNumber);

		//프리뷰 모드일때 사운드 계속 재생
		if (preViewFlg) {
			preViewFlg = false;
			return;
		}

		if (bgmFilePath != null) {
			Logger.v(TAG, "[playPageBGMSound]:pageNumber=%s", pageNumber);
			stopSound(); // 全部停止
			pageBGMPlayer = new ABVMediaPlayer(true);
			try {
				Logger.d(TAG, "MediaPlayer PAGE BGM:" + bgmFilePath);
				pageBGMPlayer.setDataSource(bgmFilePath);
				pageBGMPlayer.prepare();
				pageBGMPlayer.start();
			} catch (IOException e) {
				Logger.e(TAG, "e=" + e.getMessage(), e);
				ABVToastUtil.showMakeText(getApplicationContext(), R.string.ERROR, Toast.LENGTH_SHORT);
			}
		} else {
			// 該当するページBGMがない場合
			// 前ページのページBGMを停止させる
			if (pageBGMPlayer != null) {
				pageBGMPlayer.stop();
				pageBGMPlayer.release();
				pageBGMPlayer = null;
			} else if (tapPlayer != null) {
				tapPlayer.stop();
				tapPlayer.release();
				tapPlayer = null;
			}
			// コンテンツBGMがある場合は再生させる
			if (contentBGMPlayer != null && !contentBGMPlayer.isPlaying()) {
				Logger.v(TAG, "[playPageBGMSound]:contentBGMPlayer start");
				contentBGMPlayer.start();
			}
		}
	}

	/**
	 * WebView画面表示
	 * @param pageNumber
	 * @param objectId
	 */
	private void showWebView(String linkurl, String browserType, int pageNumber, long objectId, int objectLogId) {
		if (isAnotherViewOpenFlg == false) {
			isAnotherViewOpenFlg = true;
			preViewFlg = true;
			boolean innerBrowser = (browserType == null) || browserType.equals("0");

			if (innerBrowser) {
				ActivityHandlingHelper.getInstance().startHTMLWebActivity(this, null, linkurl, getContentId(), WEBVIEW, pageNumber, objectId, objectLogId, readingLogId);
			}
			else {
				Intent i = new Intent(Intent.ACTION_VIEW);
				if (StringUtil.isNullOrEmpty(linkurl)) {
					linkurl = "http://";
				}
				Uri u = Uri.parse(linkurl);
				i.setData(u);
				startActivity(i);
				isAnotherViewOpenFlg = false;
			}
		}
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent intent) {
		switch (requestCode) {
			case VIDEOVIEW:
			case WEBVIEW:
			case PREVIEW:
				isAnotherViewOpenFlg = false;
//			playPageBGMSound(mCurrentPageNumber); //프리뷰 모드 일때 음악재생 Bug
				break;
		}
	}

	@Override
	public void onStart() {
		super.onStart();
	}
	@Override
	public void onPause() {
		super.onPause();

		// 閲覧履歴更新
		contentDao.updateLastViewedPage(getContentId(), mCurrentPageNumber);

		//프리뷰 일 경우에는 사운드 재생 중지 Bug
		if (preViewFlg) {
			stopVideo();
		} else{
			stopVideo();
			stopSound();
		}
	}

	/**
	 * リモート操作
	 *
	 * @param json
	 */
	@Override
	public void performRemoteEvent(final JSONObject json) {
		Logger.v(TAG, "[performRemoteEvent] %s : %s", json, objectIdPopupMap);
		String cmd = json.getString(MeetingManager.CMD);
		long remoteContentId = JsonUtil.getLong(json, MeetingManager.CONTENTID);
		int pageNumber = JsonUtil.getInt(json, MeetingManager.PAGE_NUMBER);
		long remoteObjectId = JsonUtil.getLong(json, MeetingManager.OBJECTID, 0);

		if (isMarking && !cmd.equals(MeetingManager.CMD_MARKING)) {
			// マーキング状態でマーキング以外のコマンド来たらマーキングは閉じる
			closeMarkingLayout();
		}

		if (cmd.equals(MeetingManager.CMD_OPEN) && remoteContentId != -1) {
		}
		else {
			if (pageNumber >= mAllPageCount || pageNumber < 0) {
				Logger.e(TAG, "Invalid Page number : " + pageNumber);
				return;
			}

			if (cmd.equals(MeetingManager.CMD_MOVEPAGE)) { // 移動
				movePage(pageNumber);
				return;
			}

			if (pageNumber != mCurrentPageNumber) { // ページが異なる場合ジャンプ
				movePage(pageNumber);
			}

			if (cmd.equals(MeetingManager.CMD_ACTION)) { // 通常アクションボタン
				View targetView = objectIdButtonMap.get(remoteObjectId);
				if (targetView == null) {
					VideoMountAction videoMountAction = findVideoMountAction(pageNumber, remoteObjectId); // 埋め込み動画の最初のアクション
					if (videoMountAction != null) {
						performRemoteMountVideo(videoMountAction, MeetingManager.START, 0, false, false);
					}
					Logger.e(TAG, "[performRemoteEvent] targetView not found. remoteObjectId=" + remoteObjectId); // EMAILの場合はエラーが出てしまう。
					return;
				}
				Logger.v(TAG, "[performRemoteEvent] perform click. remoteObjectId=%s targetView=%s", remoteObjectId, targetView);
				targetView.performClick(); // ボタンをクリック
			}
			else if (cmd.equals(MeetingManager.CMD_LINKURLACTION)) { // PDF Link
				String url = JsonUtil.getString(json, MeetingManager.URL); // null可
				Boolean browser = JsonUtil.getBoolean(json, MeetingManager.BROWSER, false);
				showWebView(url, browser?"1":"0", pageNumber, 0, -1); // objectIdは0にする
			}
			else if (cmd.equals(MeetingManager.CMD_3DVIEWACTION)) { // 3D
				String filePath = JsonUtil.getString(json, MeetingManager.FILE_NAME);
				filePath = ABVEnvironment.getInstance().getContentCacheDirectoryPath(remoteContentId) + "/" + filePath;
				int pageidx = getPageContentArrayIndex(pageNumber); // jsonのpageオブジェクトの配列インデックスを取得
				if (pageidx == -1) {
					Logger.e(TAG, "[performRemoteEvent] pageidx not found. pageNumber=" + pageNumber);
					return;
				}
				int index = -1;
				for (Action3DImageView action3dImageView : mPageActionList.get(pageidx).array3DImage) {
					if (action3dImageView.getObjectId() == remoteObjectId) {
						index = action3dImageView.getIndex();
						break;
					}
				}
				if (index == -1) {
					Logger.e(TAG, "[performRemoteEvent] index not found. remoteObjectId=" + remoteObjectId);
				}
				else {
					mPageActionList.get(pageidx).array3DImage.get(index).setCurrentImagePath(filePath);
				}
			}
			else if (cmd.equals(MeetingManager.CMD_MOVIEACTION)) { // 埋め込み動画・差し替え動画
				String type = JsonUtil.getString(json, MeetingManager.TYPE);
				int playTime = JsonUtil.getInt(json, MeetingManager.PLAY_TIME);
				Boolean isFullScreen = JsonUtil.getBoolean(json, MeetingManager.IS_FULL_SCREEN);

				VideoMountAction videoMountAction = findVideoMountAction(pageNumber, remoteObjectId);
				if (videoMountAction != null) { // 埋め込み動画の場合
					performRemoteMountVideo(videoMountAction, type, playTime, isFullScreen, false);
				}
				else {
					Object obj = objectIdPopupMap.get(remoteObjectId);
					if (obj instanceof VideoMountAction) { // 差し替え動画の場合
						performRemoteMountVideo((VideoMountAction)obj, type, playTime, isFullScreen, true);
					}
					else if (obj instanceof FullVideoView) { // 全画面動画の場合
						performRemoteFullVideo((FullVideoView)obj, type, playTime);
//						View targetView = objectIdButtonMap.get(remoteObjectId);
//						if (targetView != null) { // 全画面動画の場合（起動のみ）
//							Logger.v(TAG, "[performRemoteEvent] perform click. remoteObjectId=" + remoteObjectId);
//							targetView.performClick(); // ボタンをクリック
//						}
//						else {
//							Logger.e(TAG, "[performRemoteEvent] target video not found. remoteObjectId=" + remoteObjectId);
//						}
					}
					else {
						Logger.e(TAG, "[performRemoteEvent] target video not found. remoteObjectId=" + remoteObjectId);
					}
				}
			}
			else if (cmd.equals(MeetingManager.CMD_QUESTIONNAIREACTION)) { // アンケート
				Float alpha = JsonUtil.getFloat(json, MeetingManager.ALPHA);
				if (alpha != null) {
					enqueteLayout.setAlpha((int) (alpha * 255));
				}
				Boolean isBigFont = JsonUtil.getBoolean(json, MeetingManager.IS_BIG_FONT_SIZE);
				if (isBigFont != null) {
					if (isBigFont) {
						enqueteLayout.setFontBig();
					}
					else {
						enqueteLayout.setFontSmall();
					}
				}

				Boolean isRight = JsonUtil.getBoolean(json, MeetingManager.IS_RIGHT);
				Logger.v(TAG, "isNormalSize: %s", isNormalSize());
				if (isRight != null && !isNormalSize()) {
					if (isRight) {
						enqueteLayout.right();
					}
					else {
						enqueteLayout.left();
					}
				}
			}
			else if (cmd.equals(MeetingManager.CMD_MARKING)) { // マーキング描画
				peformRemoteMarking(json);
			}
			else if (cmd.equals(MeetingManager.CMD_CLOSEPOPUP)) { // 各種閉じる
				closePopup(remoteObjectId);
			}
			else if (cmd.equals(MeetingManager.CMD_CURSORMODE)) { // カーソルモード切替
				Boolean isCursorMode = JsonUtil.getBoolean(json, MeetingManager.IS_CURSOR_MODE);
				mMainLayout.setRemoteDraw(isCursorMode);
			}
			else if (cmd.equals(MeetingManager.CMD_CURSOR)) { // カーソル移動
				Float x = JsonUtil.getFloat(json, MeetingManager.X);
				Float y = JsonUtil.getFloat(json, MeetingManager.Y);
				if (x != null && y != null) {
					mMainLayout.setRemoteDraw(true);
					mMainLayout.drawRemoteCursor(x, y);
				}
			} else if (cmd.equals(MeetingManager.CMD_ZOOM)) {
				Float x = JsonUtil.getFloat(json, MeetingManager.X);
				Float y = JsonUtil.getFloat(json, MeetingManager.Y);
				Float scale = JsonUtil.getFloat(json, MeetingManager.SCALE);
				if (x != null && y != null && scale != null) {
					ZoomRelativeLayout zoomLayout = mShowPageLayout.get(mCurrentPageNumber);
					ViewMargin margin = zoomLayout.getContentPageMargin();
					Matrix matrix = new Matrix();
					matrix.postScale(scale, scale);
					matrix.postTranslate(x * zoomLayout.getAuthoringScale() + margin.left, y * zoomLayout.getAuthoringScale() + margin.top);
					zoomLayout.setZoomMatrix(matrix);
				}
			}
			else {
				Logger.e(TAG, "Not Implemented Command. " + cmd);
			}
		}
	}

	private VideoMountAction findVideoMountAction(int pageNumber, long objectId) {
		int pageidx = getPageContentArrayIndex(pageNumber); // jsonのpageオブジェクトの配列インデックスを取得
		if (pageidx == -1) {
			Logger.w(TAG, "[performRemoteEvent] pageidx not found. pageNumber=" + pageNumber);
		} else {
			for (VideoMountAction videoMountAction : mPageActionList.get(pageidx).arrayVideoMount) {
				if (videoMountAction.getObjectId() == objectId) {
					return videoMountAction;
				}
			}
		}
		return null;
	}

	private void peformRemoteMarking(final JSONObject json) {
		String action = JsonUtil.getString(json, MeetingManager.MARKING_ACTION);

		if (!isMarking && !action.equals(MeetingManager.MARKING_ACTION_INVISIBLE) && !action.equals(MeetingManager.MARKING_ACTION_VISIBLE)) {
			showMarkingLayout();
		}

		handler.post(new Runnable() {
			@Override
			public void run() {
				switch (JsonUtil.getString(json, MeetingManager.MARKING_ACTION)) {
					case MeetingManager.MARKING_ACTION_DRAW:
						draw(json);
						break;
					case MeetingManager.MARKING_ACTION_CLEAR:
						mMarkingLayout.clear();
						break;
					case MeetingManager.MARKING_ACTION_SAVE:
						int markShareFlag =JsonUtil.getInt(json, MeetingManager.MARKING_SHARE);
						if ( markShareFlag == 1) {
							mMarkingLayout.chairmanMarkingShareFlag = true;
						} else {
							mMarkingLayout.chairmanMarkingShareFlag = false;
						}
						mMarkingLayout.saveClose();
						break;
					case MeetingManager.MARKING_ACTION_END:
						closeMarkingLayout();
						break;
					case MeetingManager.MARKING_ACTION_VISIBLE:
						setMarkingViewVisibility(true);
						break;
					case MeetingManager.MARKING_ACTION_INVISIBLE:
						setMarkingViewVisibility(false);
						break;
					default:
						break;
				}
			}
		});
	}

	private void draw(JSONObject json) {
		int pageWidth;
		if (mContentJSON.isPdf()) {
			PageInfoJSONData page = mPageInfoJSON.getPageData(mCurrentPageNumber);
			pageWidth = page.pageWidth;
		} else {
			pageWidth = mContentJSON.getWidth();
		}

		try {
			if (mMarkingLayout != null) {
				MarkingJson markingJson = new MarkingJson(json, (float) (mMarkingLayout.getWidth() - mMarkingLayout.margin.left - mMarkingLayout.margin.right) / pageWidth);
				mMarkingLayout.drawRemoteMarkig(markingJson);
			}
		} catch (JSONException e) {
			Logger.e(TAG, e);
		}
	}

	/**
	 * 埋め込み動画
	 *
	 * @param videoMountAction
	 * @param type
	 * @param playTime
	 * @param isFullScreen
	 * @param isChangeVideo
	 */
	private void performRemoteMountVideo(VideoMountAction videoMountAction, String type, int playTime, Boolean isFullScreen, boolean isChangeVideo) {
		if (type == null) {
		}
		else if (type.equals(MeetingManager.START)) {
			if (videoMountAction.isPrepared()) {
				videoMountAction.pauseAfterStartVideo();
			}
			else if (!isChangeVideo) {
				videoMountAction.start(videoMountAction.getVideoFile(), 0);
			}
			else { // 1秒待ってからダメなら無視
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {}
				if (videoMountAction.isPrepared()) {
					videoMountAction.pauseAfterStartVideo();
				}
			}
		}
		else if (type.equals(MeetingManager.PAUSE)) {
			videoMountAction.pauseVideo();
		}

		if (videoMountAction.isPrepared() && playTime >= 0) {
			videoMountAction.seekTo(playTime * 1000);
		}

		if (isFullScreen == null) {
		}
		else if (isFullScreen) {
			isVideoMax = true;
			mPageScrollView.setVideoMaxFlag(true);
			setToolbarVisable(false);
			if (isChangeVideo) {
				stopCurrentPageMountVideo(null, true);
				stopCurrentPageChangeVideo(videoMountAction.getIndex(), true);
			}
			else {
				stopCurrentPageMountVideo(videoMountAction.getIndex(), true);
				stopCurrentPageChangeVideo(null, true);
			}
			setToolbarVisable(false);
			videoMountAction.showMax();
		}
		else {
			setSurfaceViewVisible(!isChangeVideo, videoMountAction.getIndex());
			videoMountAction.showDefault();
		}
	}

	private void performRemoteFullVideo(FullVideoView videoView, String type, int playTime) {
		if (type == null) {
		}
		else if (type.equals(MeetingManager.START)) {
			videoView.restartVideo();
		}
		else if (type.equals(MeetingManager.PAUSE)) {
			videoView.pauseVideo();
		}

		if (playTime >= 0) {
			videoView.jump(playTime * 1000);
		}
	}


	private void movePage(int pageNumber) {
		for (long popupObjectId : objectIdPopupMap.keySet()) {
			closePopup(popupObjectId);
		}
		jumpToPage(pageNumber);
	}

	private void closePopup(long objectId) {
		Object popup = objectIdPopupMap.get(objectId);
		if (popup != null) {
			Logger.v(TAG, "objectId=%s popup=%s", objectId, popup);
			if (popup instanceof EnqueteLayout) {
				((EnqueteLayout)popup).close();
			}
			else if (popup instanceof FullVideoView) {
				((FullVideoView)popup).close();
				fullVideoView = null;
			}
			else if (popup instanceof View) {
				((View)popup).setVisibility(View.GONE);
			}
			else if (popup instanceof AlertDialog) {
				((AlertDialog)popup).cancel();
			}
			objectIdPopupMap.remove(objectId);
		}
	}

	/**
	 * マーキングレイアウト表示
	 */
	private void showMarkingLayout() {
		// マーキングしている間は画面を固定
		if (isRotatable()) {
			setFixedOrientation(true);
		}

		if (!isMarking) {
			for (MarkingView markingView : mMarkingViewList) {
				if (markingView.getPageNum() == mCurrentPageNumber) {
					markingView.setVisibility(View.GONE);
				}
			}

			// オーサリングのページサイズでマーキングを保存するため情報取得
			int pageWidth;
			int pageHeight;
			if (mContentJSON.isPdf()) {
				PageInfoJSONData page = mPageInfoJSON.getPageData(mCurrentPageNumber);
				pageWidth = page.pageWidth;
				pageHeight = page.pageHeight;
			}
			else {
				pageWidth = mContentJSON.getWidth();
				pageHeight = mContentJSON.getHeight();
			}

			ViewMargin margin = (mShowPageLayout.get(mCurrentPageNumber) == null)? null: mShowPageLayout.get(mCurrentPageNumber).getContentPageMargin();
			// （mMarkingLayoutがnullでない）回転された場合などマージンだけ変更
			if (mMarkingLayout == null) {
				mMarkingLayout = new MarkingLayout(this, mContentDto, mCurrentPageNumber, pageWidth, pageHeight, margin, contentLogic, new MarkingLayout.OnMarkingListener() {
					@Override
					public void close() {
						closeMarkingLayout();
					}
				});
				if (mCurrentPageNumber <= 0) {
					mMarkingLayout.setBackPageStatus(false);
				}
				if (mCurrentPageNumber>= (mAllPageCount - 1)) {
					mMarkingLayout.setNextPageStatus(false);
				}
			} else {
				mMarkingLayout.setTouchDrawViewMargin(margin);
			}
			mMarkingLayout.setUnAuthorizedContentListener(unAuthorizedContentListener);
			mMarkingLayout.setMovePageListener(movePageListener);
			isMarking = true;
			setToolbarVisable(false);
			tbtnMarking.setChecked(false);
			RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
			mMainLayout.addView(mMarkingLayout, params);

			if (meetingManager.isSendable()) {
				JSONObject json = new JSONObject();
				json.put(MeetingManager.MARKING_ACTION, MeetingManager.MARKING_ACTION_START);
				meetingManager.sendWs(MeetingManager.CMD_MARKING, contentId, mCurrentPageNumber, null, json);
			}
		}
	}

	private void closeMarkingLayout() {
		mMainLayout.removeView(mMarkingLayout);
		isMarking = false;
		tbtnMarking.setChecked(true);

		for (MarkingView markingView : mMarkingViewList) {
			markingView.reLoad();
		}
		mMarkingLayout = null;

		// 画面を固定を解除
		if (isRotatable()) {
			setFixedOrientation(false);
		}
	}

	//앙케이트 레이아웃
	private void showEnqueteLayout(EnqueteWebView webView, ActionInfoJSON actionInfoJSON) {
		isEnqueteOpening = true;
		isEnqueteFullScreen = (actionInfoJSON.getFullScreen() == 1 || isNormalSize());
		String htmlPath = contentLogic.getHtmleFilePath(getContentId(), actionInfoJSON.getEnquete(), isEnqueteFullScreen);
		final long abObjectId = actionInfoJSON.getObjectId();
		final long abEnqueteId = actionInfoJSON.getEnqueteId();
		final int saveAs = actionInfoJSON.getSaveAs();

		final int pixelWidth = isEnqueteFullScreen? mDisplaySize.width: (int) (getResources().getDisplayMetrics().density * EnqueteLayout.HALF_WIDTH);
		Logger.d(TAG, "pixel_width=%s density=%s", pixelWidth, getResources().getDisplayMetrics().density);

		enqueteLayout = new EnqueteLayout(this, webView, getContentId(), mCurrentPageNumber, actionInfoJSON, htmlPath, pixelWidth, isEnqueteFullScreen, new EnqueteLayout.OnWebViewListener() {

			@Override
			public void close() {
				if (saveAs == 1) {
					enqueteMap.put(abEnqueteId, enqueteLayout);
				}

				isEnqueteOpening = false;
				isEnquete = false;
				mMainLayout.removeView(enqueteLayout);
				if (meetingManager.isSendable()) {
					meetingManager.sendWs(MeetingManager.CMD_CLOSEPOPUP, getContentId(), mCurrentPageNumber, abObjectId, null);
				}
			}

			@Override
			public void Left() {
				setToolbarVisable(false);
				mMainLayout.removeView(enqueteLayout);
				RelativeLayout.LayoutParams params = createParam(pixelWidth , FP);
				mMainLayout.addView(enqueteLayout, params);
				isEnqueteLeft = true;
				if (meetingManager.isSendable()) {
					JSONObject json = new JSONObject();
					json.put(MeetingManager.IS_RIGHT, false);
					meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, getContentId(), mCurrentPageNumber, abObjectId, json);
				}
			}
			@Override
			public void Right() {
				setToolbarVisable(false);
				mMainLayout.removeView(enqueteLayout);
				RelativeLayout.LayoutParams param1 = createParam(pixelWidth ,ViewGroup.LayoutParams.MATCH_PARENT);
				param1.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
				mMainLayout.addView(enqueteLayout, param1);
				isEnqueteLeft = false;
				if (meetingManager.isSendable()) {
					JSONObject json = new JSONObject();
					json.put(MeetingManager.IS_RIGHT, true);
					meetingManager.sendWs(MeetingManager.CMD_QUESTIONNAIREACTION, getContentId(), mCurrentPageNumber, abObjectId, json);
				}
			}

			@Override
			public void TouchEvent() {
				isSeeking = true;
			}

			@Override
			public void DisallowMovePage() {
				isDisallowMovePage = true;
			}
		});
		isEnquete = true;
		objectIdPopupMap.put(abObjectId, enqueteLayout);

		setToolbarVisable(false);
		RelativeLayout.LayoutParams params;
		if (isEnqueteFullScreen) {
			params = createParam(FP , FP);
		} else{
			params = createParam(pixelWidth, FP);
			if (!isEnqueteLeft) {
				params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
			}
		}

		mMainLayout.addView(enqueteLayout, params);
	}

	// メインレイアウトクラス
	private class MmainLayout extends RelativeLayout {

		private boolean isTouching;
		private float mX;
		private float mY;
		private Bitmap bitmap;
		private float bitmapW;
		private float bitmapH;
		private boolean isRemoteDraw;

		public MmainLayout(Context context) {
			super(context);

			bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_cursor);
			bitmapW = bitmap.getWidth() / 2;
			bitmapH = bitmap.getHeight() / 2;
		}

		// カーソルを最上部に書くためにdispatchDrawで描画
		@Override
		protected void dispatchDraw(Canvas canvas) {
			super.dispatchDraw(canvas);
			if (isTouching && isCursorModeEnable() || isRemoteDraw) {
				canvas.drawBitmap(bitmap, mX  - bitmapW, mY  - bitmapH - convertDensitySize(20), null);
			}
		}
		// カーソル描画
		public void drawCursor(int action , float x,float y) {
			switch (action) {
				case MotionEvent.ACTION_DOWN:
					isTouching = true;
					mX = x;
					mY = y;
					invalidate();
					break;
				case MotionEvent.ACTION_MOVE:
					isTouching = true;
					mX = x;
					mY = y;
					invalidate();
					break;
				case MotionEvent.ACTION_UP:
					//isTouching = false;
					invalidate();
					break;
			}

			if (isCursorModeEnable() && !slide.isChecked() && meetingManager.isSendable()) {
				ZoomRelativeLayout zoomRelativeLayout = mShowPageLayout.get(mCurrentPageNumber);
				if (zoomRelativeLayout == null) {
					Logger.e(TAG, "zoomRelativeLayout is null");
					return;
				}
				Logger.v(TAG, "AuthoringScale : " + zoomRelativeLayout.getAuthoringScale());
				JSONObject json = new JSONObject();
				if (getMargin() != null) {
					json.put(MeetingManager.X, (x - bitmapW - getMargin().left) / zoomRelativeLayout.getAuthoringScale());
					json.put(MeetingManager.Y, (y - bitmapH - getMargin().top) / zoomRelativeLayout.getAuthoringScale());
				}
				meetingManager.sendWs(MeetingManager.CMD_CURSOR, getContentId(), mCurrentPageNumber, null, json);
			}
		}

		// カーソル描画
		public void drawRemoteCursor(float x, float y) {
			Logger.v(TAG, "drawRemoteCursor x=%s y=%s", x, y);
			if (onCreateFinish && isRemoteDraw) {
				ZoomRelativeLayout zoomRelativeLayout = mShowPageLayout.get(mCurrentPageNumber);
				if (zoomRelativeLayout == null) {
					Logger.e(TAG, "zoomRelativeLayout is null");
					return;
				}
				Logger.v(TAG, "AuthoringScale : " + zoomRelativeLayout.getAuthoringScale());
				if (getMargin() != null) {
					mX = x * zoomRelativeLayout.getAuthoringScale() + bitmapW + getMargin().left;
					mY = y * zoomRelativeLayout.getAuthoringScale() + bitmapH + getMargin().top;
				}
				invalidate();
			}
		}

		public void setRemoteDraw(boolean remoteDraw) {
			isRemoteDraw = remoteDraw;
		}

		private ViewMargin getMargin() {
			ZoomRelativeLayout zoomRelativeLayout = mShowPageLayout.get(mCurrentPageNumber);
			if (zoomRelativeLayout != null) {
				return zoomRelativeLayout.getContentPageMargin();
			}
			return null;
		}

	}

	private int getPageContentArrayIndex(int pageNumber) {
		int retIndex = -1;
		for (int i = 0; i < mPageActionList.size(); i++) {
			if (mPageActionList.get(i).getPageNumber() == pageNumber) {
				retIndex = i;
				break;
			}
		}
		return retIndex;
	}

	private void videoMaxToDefault() {
		isVideoMax = false;
		mPageScrollView.setVideoMaxFlag(false);
		int pageidx = getPageContentArrayIndex(mCurrentPageNumber);

		ArrayList<VideoMountAction> arrayVideoMount = mPageActionList.get(pageidx).arrayVideoMount;
		for (int i = 0; i < arrayVideoMount.size(); i++) {
			if (arrayVideoMount.get(i).getSurfaceVisibility() == View.VISIBLE) {
				arrayVideoMount.get(i).showDefault();
				setSurfaceViewVisible(true, i);     //他の動画を表示
				return;
			}
		}

		ArrayList<VideoMountAction> arrayVideoChange = mPageActionList.get(pageidx).arrayVideoChange;
		for (int i = 0; i < arrayVideoChange.size(); i++) {
			if (arrayVideoChange.get(i).getSurfaceVisibility() == View.VISIBLE) {
				arrayVideoChange.get(i).showDefault();
				setSurfaceViewVisible(false, i);     //他の動画を表示
				return;
			}
		}
	}

	public void setDefaultVideo() {
		for (int i = 0; i < mPageActionList.size(); i++) {
			for (int j = 0; j < mPageActionList.get(i).arrayVideoMount.size(); j++) {
				mPageActionList.get(i).arrayVideoMount.get(j).setDefaultPosition();
			}
			for (int j = 0; j < mPageActionList.get(i).arrayVideoChange.size(); j++) {
				mPageActionList.get(i).arrayVideoChange.get(j).setDefaultPosition();
			}
		}
	}

	public void resetScrollStatus() {
		mScrollStatus = ScrollStatus.NONE;
	}

	/**
	 * PDFサイズをオーサリング上のサイズに変換するクラス
	 * @author jang
	 *
	 */
	private static class PDFAuthoringSize {
		private static final float EDIT_VIEW_LAND_WIDTH = 1024f;  // AATでiPadのサイズに合わせた長辺のサイズ
		private static final float EDIT_VIEW_LAND_HEIGHT = 748f;  // AAtでiPadのサイズに合わせた短辺のサイズ
		private static final float EDIT_VIEW_PORT_WIDTH = 768f;   // AATでiPadのサイズに合わせた短辺のサイズ
		private static final float EDIT_VIEW_PORT_HEIGHT = 1004f; // AAtでiPadのサイズに合わせた長辺のサイズ

		public float width;
		public float height;

		public PDFAuthoringSize(Size size) {
			float authoringWidth;
			float authoringHeight;
			if (size.width > size.height) {
				authoringWidth = EDIT_VIEW_LAND_WIDTH;
				authoringHeight = EDIT_VIEW_LAND_HEIGHT;
			} else {
				authoringWidth = EDIT_VIEW_PORT_WIDTH;
				authoringHeight = EDIT_VIEW_PORT_HEIGHT;
			}
			float scale = Math.min(authoringWidth / size.width, authoringHeight / size.height);
			width = scale * size.width;
			height = scale * size.height;
		}

	}

	@Override
	public int getCurrentPageNumber() {
		return mCurrentPageNumber;
	}

	public int getLThumViewSize() {
		return mLThumViewSize;
	}

	@Override
	protected void releaseInit() {
		mActivityFinishFlg = true;
	}

	/**
	 * 会議室機能
	 * 拡大・縮小関連のアクション情報を転送
	 * @param dx float PDF座標左上
	 * @param dy float PDF座標左上
	 * @param scale float 拡大率
	 */
	public void callZoomAction(float dx, float dy, float scale, float width, float height) {
		if (meetingManager.isSendable()) {
			ViewMargin viewMargin = mShowPageLayout.get(mCurrentPageNumber).getContentPageMargin();
			PageInfoJSONData pageInfoJson =  mPageInfoJSON.getPageData(mCurrentPageNumber);
			float scaleWidth = width / scale / pageInfoJson.pageWidth;
			float scaleHeight = height / scale / pageInfoJson.pageHeight;
			dx = (dx  - viewMargin.left) / scaleWidth;
			dy = (dy - viewMargin.top) / scaleHeight;
			Logger.d(TAG, "callZoomAction:x=%s, y=%s, scale=%s", dx, dy, scale);
			final JSONObject json = new JSONObject();
			json.put(MeetingManager.X, dx);
			json.put(MeetingManager.Y, dy);
			json.put(MeetingManager.SCALE, scale);
			meetingManager.sendWs(MeetingManager.CMD_ZOOM, getContentId(), mCurrentPageNumber, null, json);

			// Test Code
//			handler.post(new Runnable() {
//				@Override
//				public void run() {
//					ABookAlertDialog alertDialog = AlertDialogUtil.createABookAlertDialog(GuideViewActivity.this);
//					alertDialog.setTitle("Remote JSON");
//					String message = json.toString().replace(",", "\n");
//					alertDialog.setMessage(message);
//					alertDialog.setNegativeButton(R.string.ok, null);
//					alertDialog.show();
//				}
//			});

		}
	}

	public void callZoomLog(double dx, double dy, String eventType) {
		ZoomRelativeLayout zoomRelativeLayout = mShowPageLayout.get(mCurrentPageNumber);
		if (zoomRelativeLayout == null) {
			Logger.e(TAG, "zoomRelativeLayout is null");
			return;
		}

		// オーサリング座標に変換
		dx = dx / zoomRelativeLayout.getAuthoringScale();
		dy = dy / zoomRelativeLayout.getAuthoringScale();

		Logger.d(TAG, "callZoomLog dx:" + dx + ",dy:" + dy);

		ContentLogUtil.getInstance().insertZoomLog(contentId, readingLogId, mCurrentPageNumber, dx, dy, eventType);
	}

	private UnAuthorizedContentListener unAuthorizedContentListener = new UnAuthorizedContentListener() {
		@Override
		public void unAuthorizedContentNotification(String msg) {
			showUnAuthorizedContentWarningDialog(msg);
		}
	};

	private MovePageInterface movePageListener = new MovePageInterface() {
		@Override
		public void nextPage() {
			showProgressPopup();
			moveTo(1);
			handler.postDelayed(new Runnable() {
				@Override
				public void run() {
					mMarkingLayout.setBackPageStatus(true);
					if (mCurrentPageNumber >= mAllPageCount-1) {
						mMarkingLayout.setNextPageStatus(false);
					}
					closeMarkingLayout();
					showMarkingLayout();
					closeProgressPopup();
				}
			}, intervalAddOrRemovePage);
		}
		@Override
		public void backPage() {
			showProgressPopup();
			moveTo(-1);
			handler.postDelayed(new Runnable() {
				@Override
				public void run() {
					mMarkingLayout.setNextPageStatus(true);
					if (mCurrentPageNumber <= 0) {
						mMarkingLayout.setBackPageStatus(false);
					}
					closeMarkingLayout();
					showMarkingLayout();
					closeProgressPopup();
				}
			}, intervalAddOrRemovePage);
		}
	};
}

