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

import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.SparseBooleanArray;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckedTextView;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshGridView;

import net.lingala.zip4j.exception.ZipException;

import org.json.adf.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import jp.agentec.abook.abv.bl.acms.client.AcmsClient;
import jp.agentec.abook.abv.bl.acms.client.json.OperationDataJSON;
import jp.agentec.abook.abv.bl.acms.client.parameters.GetOperationDataParameters;
import jp.agentec.abook.abv.bl.acms.type.DownloadStatusType;
import jp.agentec.abook.abv.bl.acms.type.OperationType;
import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.Callback;
import jp.agentec.abook.abv.bl.common.CommonExecutor;
import jp.agentec.abook.abv.bl.common.Constant;
import jp.agentec.abook.abv.bl.common.Constant.PushMessageSendType;
import jp.agentec.abook.abv.bl.common.Constant.ReportType;
import jp.agentec.abook.abv.bl.common.Constant.TaskReportLevel;
import jp.agentec.abook.abv.bl.common.constant.ABookKeys;
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.data.dao.OperationContentDao;
import jp.agentec.abook.abv.bl.data.dao.OperationDao;
import jp.agentec.abook.abv.bl.data.dao.TaskDao;
import jp.agentec.abook.abv.bl.data.dao.TaskReportDao;
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.bl.dto.FixPushMessageDto;
import jp.agentec.abook.abv.bl.dto.OperationContentDto;
import jp.agentec.abook.abv.bl.dto.OperationDto;
import jp.agentec.abook.abv.bl.dto.OperationGroupMasterDto;
import jp.agentec.abook.abv.bl.dto.PushMessageDto;
import jp.agentec.abook.abv.bl.dto.TaskDto;
import jp.agentec.abook.abv.bl.dto.TaskReportDto;
import jp.agentec.abook.abv.bl.logic.AbstractLogic;
import jp.agentec.abook.abv.bl.logic.OperationGroupMasterLogic;
import jp.agentec.abook.abv.bl.logic.OperationLogic;
import jp.agentec.abook.abv.bl.logic.PushMessageLogic;
import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.launcher.android.R;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType.OperationLocationType;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import jp.agentec.abook.abv.ui.common.constant.ErrorCode;
import jp.agentec.abook.abv.ui.common.constant.ErrorMessage;
import jp.agentec.abook.abv.ui.common.dialog.ABookAlertDialog;
import jp.agentec.abook.abv.ui.common.helper.ProgressDialogHelper;
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.KeyboardUtils;
import jp.agentec.abook.abv.ui.common.util.PatternStringUtil;
import jp.agentec.abook.abv.ui.common.view.ABVListDialog;
import jp.agentec.abook.abv.ui.common.view.ABVPopupListWindow;
import jp.agentec.abook.abv.ui.common.view.ABVBatchSyncView;
import jp.agentec.abook.abv.ui.home.adapter.FixPushMessageAdapter;
import jp.agentec.abook.abv.ui.home.adapter.OperationSelectAdapter;
import jp.agentec.abook.abv.ui.home.adapter.PushMessageListAdapter;
import jp.agentec.abook.abv.ui.home.adapter.HierarchyOperationGroupListAdapter;
import jp.agentec.abook.abv.ui.home.adapter.UnreadPushMessageListAdapter;
import jp.agentec.abook.abv.ui.home.helper.ABookCheckWebViewHelper;
import jp.agentec.abook.abv.ui.home.helper.ABookPermissionHelper;
import jp.agentec.abook.abv.ui.home.helper.ActivityHandlingHelper;
import jp.agentec.abook.abv.ui.home.helper.HomeOperationListHelper;
import jp.agentec.abook.abv.ui.home.helper.OperationGroupMasterListHelper;
import jp.agentec.abook.abv.ui.home.helper.OperationListHelper;
import jp.agentec.adf.util.DateTimeFormat;
import jp.agentec.adf.util.DateTimeUtil;
import jp.agentec.adf.util.FileUtil;
import jp.agentec.adf.util.StringUtil;

import static jp.agentec.abook.abv.ui.home.activity.CaptureQRCodeActivity.OPERATION_QRCODE_SCHEME;
import static jp.agentec.abook.abv.ui.home.activity.CaptureQRCodeActivity.QRCODE_OPERATION_ID;

/**
 * Created by leej on 2018/08/17
 */

public class OperationListActivity extends OperationActivity {
    private static final String TAG = "OperationListActivity";

    private ImageButton mViewModeButton;           // 左上
    private ImageButton mSearchButton;             // 検索ボタン
    private ImageButton mCategoryLocationButton;   // カテゴリ選択ボタン
    private ImageButton mOperationBatchSyncButton;              // カテゴリの一括同期ボタン
    private ImageButton mQrCodeButton;             // QRCodeボタン

    private List<OperationDto> mOperationList;

    public String mSearchWord;
    public String mStartDateStr;
    public String mEndDateStr;

    private EditText mSearchTextView;
    private TextView mStartDate;
    private TextView mEndDate;
    private TextView mTitleView;

    private LinearLayout mReportTypeLayoutLabel;
    private LinearLayout mReportTypeLayoutButton;
    private Button mReportTypeAllButton;
    private Button mReportTypeDefaultButton;
    private Button mReportTypeRoutineTaskButton;

    private Dialog mSearchDialog;
    private Date mOperationLastEditDate;
    private boolean isSyncGetTaskFileError;

    private Dialog mPanoEntryDialog;

    private OperationContentDao mOperationContentDao = AbstractDao.getDao(OperationContentDao.class);

    private TaskReportDao mTaskReportDao = AbstractDao.getDao(TaskReportDao.class);
    private OperationLogic mOperationLogic = AbstractLogic.getLogic(OperationLogic.class);
    private TaskDao mTaskDao = AbstractDao.getDao(TaskDao.class);

    private PushMessageLogic mPushMessageLogic = AbstractLogic.getLogic(PushMessageLogic.class);

    private ImageView mPanoCotnentImageView;
    private TextView  mPanoContentNameTextView;
    private Uri mSelectPanoContentUri;

    private final static int ABOOK_CHECK_OPERATION_PANO_CONTENT_IMAGE = 201;
    private final static int DELAY_2SECONDS_OPERATION_MAX_COUNT = 10;

    private Dialog mOperationSelectDialog;
    private ListView mOperationSelectListView;
    private OperationSelectAdapter mOperationSelectAdapter;
    private UnreadPushMessageListAdapter mUnreadPushMessageListAdapter;

    private File mLocalFile;
    private boolean activityResultFlg;
    private ListView mFixPushMessageListView;

    private Dialog mPushMessageSendDialog;
    private int mSelectedFixPuchMessagePosition;
    private int mSendType;

    private OperationListHelper mListHelper = null;

    private ArrayList<Integer> mAllOperationReportTypes;

    private Map<Integer, Integer> operationCountMap;
    private OperationGroupMasterLogic mOperationGroupMasterLogic = AbstractLogic.getLogic(OperationGroupMasterLogic.class);
    private ABVListDialog mShowDialog;
    private OperationDao mOperationDao = AbstractDao.getDao(OperationDao.class);

    // 作業種別のサービスオプション値を保持用フラグ
    private boolean mOperationGroupMasterServiceOperationFlg;

    public boolean mAutoSyncingFlg;
    public Long mAutoSyncOpenOperationId = null;

    public Long mQrCodeOperationId = null;
    private ListView mOperationPushMessageListView;

    private Long mSyncTargetOperationId = null;
    // ビューの作成
    private class ReloadHandler implements Runnable {
        @Override
        public void run() {
            View child = mListHelper.getOperationView();
            ViewGroup parent = (ViewGroup) child.getParent();
            if (parent != null) {
                parent.removeView(child);
            }
            FrameLayout vg = (FrameLayout) findViewById(R.id.operation_list_layout);
            vg.removeAllViews();
            vg.addView(child);
            // ツールバーのビューモードイメージ変更
            if (child instanceof PullToRefreshGridView) {
                mViewModeButton.setBackground(getRDrawable(R.drawable.ic_display_list));
            } else {
                mViewModeButton.setBackground(getRDrawable(R.drawable.ic_display_pannel));
            }
            closeProgressPopup();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ac_operation_list);
        mListHelper = getListHelper();

        // 上ツールバー
        mViewModeButton = (ImageButton) findViewById(R.id.btn_view_mode);
        mSearchButton = (ImageButton) findViewById(R.id.btn_search);
        mQrCodeButton = findViewById(R.id.btn_qrcode);
        mTitleView = (TextView) findViewById(R.id.title);
        // カテゴリボタン
        mCategoryLocationButton = (ImageButton) findViewById(R.id.btn_category_location);
        mOperationBatchSyncButton = (ImageButton) findViewById(R.id.btn_batch_sync);

        mViewModeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (getABVUIDataCache().getViewMode() == AppDefType.ViewMode.PANEL) {
                    getABVUIDataCache().setViewMode(AppDefType.ViewMode.LIST);
                } else {
                    getABVUIDataCache().setViewMode(AppDefType.ViewMode.PANEL);
                }
                setOperationListView();
            }
        });
        mSearchButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSearchDialog();
            }
        });
        mQrCodeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showQrCodeReaderActivity();
            }
        });
        mTitleView.setText(PatternStringUtil.patternToString(getApplicationContext(),
                R.string.operation_list,
                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));

        // カテゴリ選択機能
        // サービスオプション(作業種別使用)をセット
        mOperationGroupMasterServiceOperationFlg = ABVDataCache.getInstance().serviceOption.isOperationGroupMaster();

        mSelectedFixPuchMessagePosition = 0;
        mSendType = 0;
        // 一括同期ボタン
        mOperationBatchSyncButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // ネットワーク通信チェック
                if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
                    showSimpleAlertDialog(getString(R.string.app_name), getString(R.string.request_network_connection));
                    return;
                }

                // 新着更新チェック
                if (contentRefresher.isRefreshing()) {
                    showSimpleAlertDialog(getString(R.string.app_name), getString(R.string.msg_batch_sync_new_content_updating));
                    return;
                }

                // 会議室接続中
                if (ActivityHandlingHelper.getInstance().isMeetingConnected()) {
                    ABVToastUtil.showMakeText(OperationListActivity.this, R.string.msg_batch_sync_fail_meeting_room_connected, Toast.LENGTH_SHORT);
                    return;
                }
                showBatchSyncDialog();
            }
        });
        if (!StringUtil.isNullOrEmpty(getIntent().getStringExtra(AppDefType.PushMessageKey.operationId))) {
            final long operationId = Long.parseLong(getIntent().getStringExtra(AppDefType.PushMessageKey.operationId));
            String message = getIntent().getStringExtra(AppDefType.PushMessageKey.message);
            if (operationId > 0) {
                final ABookAlertDialog alertDialog = AlertDialogUtil.createAlertDialog(this, getRString(R.string.app_name), message);
                // リソースパターンの適用
                alertDialog.setPositiveButton(PatternStringUtil.patternToInt(getApplicationContext(),
                                                R.string.work_report,
                                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)),
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int whichButton) {
                        if (contentRefresher.isRefreshing()) {
                            // リソースパターンの適用
                            ErrorMessage.showErrorMessageToast(OperationListActivity.this, PatternStringUtil.patternToInt(getApplicationContext(),
                                                                                                    R.string.msg_routineTask_report_disable_refreshing,
                                                                                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                        } else if(ActivityHandlingHelper.getInstance().isMeetingConnected()) {
                            // リソースパターンの適用
                            ErrorMessage.showErrorMessageToast(OperationListActivity.this, PatternStringUtil.patternToInt(getApplicationContext(),
                                                                                                    R.string.msg_routineTask_report_disable_meeting_room,
                                                                                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                        } else {
                            OperationDto operationDto = mOperationLogic.getOperation(operationId);

                            if (operationDto == null) {
                                // リソースパターンの適用
                                ErrorMessage.showErrorMessageToast(OperationListActivity.this, PatternStringUtil.patternToInt(getApplicationContext(),
                                                                                                        R.string.msg_routineTask_report_disable_no_operation,
                                                                                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                            } else  if (operationDto.needSyncFlg) {
                                // リソースパターンの適用
                                ErrorMessage.showErrorMessageToast(OperationListActivity.this, PatternStringUtil.patternToInt(getApplicationContext(),
                                                                                                        R.string.msg_routineTask_report_disable_not_updated,
                                                                                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                            } else {
                                startTaskDirectionOrReportView(operationDto);
                            }
                        }

                        dialog.dismiss();
                    }
                });

                alertDialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int whichButton) {
                        dialog.dismiss();
                    }
                });

                alertDialog.show();
            }
        }
        mAllOperationReportTypes = getOperationReportTypeList(true);
        createCommonToolber();
        mOperationHomeButton.setEnabled(false);
        // 作業リスト更新、ツールバー更新
        setOperationListView();

        mOperationPushMessageListView = (ListView) findViewById(R.id.lv_message_list);
        reloadOperationPushMessageListView();
    }

    /**
     * ホーム画面下のツールバー、各アイコンの有効・無効
     */
    private void configurationToolbarIcon() {

        if (ABVDataCache.getInstance().serviceOption.isUnableIOReport()) {
            findViewById(R.id.print_layout).setVisibility(View.VISIBLE);
            mQuickReportPrintButton.setVisibility(View.VISIBLE);
        } else {
            findViewById(R.id.print_layout).setVisibility(View.GONE);
            mQuickReportPrintButton.setVisibility(View.GONE);
        }
        // フィルター選択判定
        checkSelectedFilterType();
        // 作業種別表示・非表示
        if (mOperationGroupMasterServiceOperationFlg) {
            // サービスオプションON
            mCategoryLocationButton.setVisibility(View.VISIBLE);

            if (getABVUIDataCache().getOperationGroupMasterMode() == OperationLocationType.CATEGORY) {
                // カテゴリ選択時
                setCategoryImage(true);
                mTitleView.setText(R.string.title_category);
                // 検索ワード削除
                clearSearch();
                // 検索ボタンを無効にする
                mSearchButton.setEnabled(false);
                mOperationBatchSyncButton.setVisibility(View.VISIBLE);
            } else {
                // 全て
                // 検索ボタン、カテゴリボタンを活性化
                mSearchButton.setEnabled(true);
                mCategoryLocationButton.setEnabled(true);
                setCategoryImage(false);
                mTitleView.setText(R.string.title_all_operation);
                mOperationBatchSyncButton.setVisibility(View.GONE);
            }
        } else {
            // サービスオプションOFF
            mTitleView.setText(R.string.title_all_operation);
            // アイコン非表示
            setCategoryImage(false);
            mCategoryLocationButton.setVisibility(View.GONE);
            mOperationBatchSyncButton.setVisibility(View.GONE);
            // 検索ボタンを活性化
            mSearchButton.setEnabled(true);
        }

        // 検索済みの場合、タイトルを「検索結果」にする。検索結果表示時は、カテゴリボタン非活性化
        if (isSearched()) {
            mTitleView.setText(R.string.search_result);
            // TODO:アイコン差替え
            mCategoryLocationButton.setEnabled(false);
        }
        mQrCodeButton.setEnabled(!isSearched());
    }

    /**
     * ビューを作り直す。
     */
    public void setOperationListView() {
        mListHelper = getListHelper();
        handler.post(new ReloadHandler());
        configurationToolbarIcon();
    }

    // ビューを作り直さずにリストだけ更新する
    public void refreshOperationList() {
        Logger.d(TAG, "refreshContentList");

        mListHelper.refreshList();
        configurationToolbarIcon();
    }

    @Override
    public void onRefreshedContent(final boolean result, long contentId, Exception e) {
        final Exception ex = e;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (ex != null) {
                    // ヘッダーの新着更新処理を完了にさせる
                    stopUpdateAnimation();

                    final ABookAlertDialog messageDialog = AlertDialogUtil.createAlertDialog(OperationListActivity.this, R.string.app_name);
                    if (ex.getMessage().equals("initializeMasterData")) { //マスターデータ取得失敗時
                        messageDialog.setMessage(getString(R.string.failed_get_master_data));
                    } else {
                        messageDialog.setMessage(getString(R.string.msg_new_content_update_error));
                    }
                    messageDialog.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int whichButton) {
                            messageDialog.dismiss();
                        }
                    });
                    messageDialog.show();
                }
                if (!contentRefresher.isRefreshing()) {
                    // 新着処理が終わったら以下の処理が実行
                    stopUpdateAnimation();
                    // 新着更新時間の更新
                    getABVUIDataCache().saveLastUpdateTime();
                    // リソースパターンを取得し、ローカルに保存する。
                    setResourcePattern();
                    // マスタデータ最新更新する時fetchDateをローカルに保存する。
                    setMasterDataFetchDate();

                    if (mOperationGroupMasterServiceOperationFlg == ABVDataCache.getInstance().serviceOption.isOperationGroupMaster()) {
                        // サービスオプションが変わってない場合は、ビューは作らずにデータのみ更新
                        refreshOperationList();
                    } else {
                        // 初期化
                        getABVUIDataCache().clearOperationGroupMaster();
                        mOperationGroupMasterServiceOperationFlg = ABVDataCache.getInstance().serviceOption.isOperationGroupMaster();
                        // 作業種別の選択画面を閉じる
                        closeOperationGroupMasterDialog();
                        // ビューを作り直す
                        setOperationListView();
                    }
                    //上部の未読プッシュメッセージ一覧リロード
                    reloadOperationPushMessageListView();

                    if (isAutoSync()) {
                        if (mAutoSyncingFlg) {
                            if (result) {
                                // content update success
                                List<OperationDto> needSyncOperationList = new ArrayList<>();
                                if (mAutoSyncOpenOperationId != null) {
                                    OperationDto operationDto = mOperationLogic.getOperation(mAutoSyncOpenOperationId);
                                    if (operationDto != null && operationDto.needSyncFlg) {
                                        needSyncOperationList.add(operationDto);
                                    }
                                } else {
                                    needSyncOperationList.addAll(mOperationDao.getNeedSyncAllOperation());
                                }
                                List<OperationDto> needSyncCheckArray = mOperationLogic.needSyncCheckArray(needSyncOperationList);

                                if (mSyncTargetOperationId != null && mSyncTargetOperationId != -1) {
                                    if (ABVDataCache.getInstance().serviceOption.isUnableIOReport()) {
                                        List<OperationDto> categorySyncOperationList = mListHelper.getNeedSyncOperationList();
                                        needSyncCheckArray.addAll(categorySyncOperationList);
                                    }
                                    OperationDto operationDto = mOperationLogic.getOperation(mSyncTargetOperationId);
                                    if (operationDto != null && operationDto.needSyncFlg) {
                                        needSyncCheckArray.add(operationDto);
                                    }
                                    mSyncTargetOperationId = null;
                                    needSyncCheckArray = mOperationLogic.deduplicateOperationDto(needSyncCheckArray);
                                }
                                Logger.i("needSyncCheckArray.size() = " + needSyncCheckArray.size() + ", mSyncTargetOperationId = " + mSyncTargetOperationId);
                                if (needSyncCheckArray.size() > 0) {
                                    categoryBatchSync(needSyncCheckArray);
                                } else {
                                    // donot need sync
                                    autoSyncOperationDone(true);
                                }
                            } else {
                                // content update fail
                                autoSyncOperationDone(false);
                            }
                        }
                        return;
                    }
                    //「I/O 帳票使用」がYESのみ、新着更新処理完了後、一括同期処理を開始する。
                    if (ABVDataCache.getInstance().serviceOption.isUnableIOReport()) {
                        if (mAutoBatchSyncFlg) {
                            closeProgressPopup();
                            List<OperationDto> needSyncOperationList = mListHelper.getNeedSyncOperationList();
                            if (needSyncOperationList.size() != 0) {
                                categoryBatchSync(needSyncOperationList);
                            }
                            mAutoBatchSyncFlg = false;
                        }
                    }
                }
            }
        });
    }

    // 回転時、画面リロード
   @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // 画面リロード
        setOperationListView();
    }

    @Override
    public void onResume() {
        Logger.i(TAG, "onResume:start");
        super.onResume();
        refreshOperationList();

        final long operationId = getUserPref(AppDefType.UserPrefKey.SYNC_TARGET_OPERATION_ID, -1L);
        // 作業指示・報告からプロジェクト一覧へ戻った時の同期処理
        if (ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            if (isAutoSync()) {
                mSyncTargetOperationId = operationId;
                // delay for showProgressView
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        autoSyncOperation();
                    }
                }, 100);

            } else {

                if (operationId != -1) {
                    final OperationDto operationDto = mOperationLogic.getOperation(operationId);
                    // リソースパターンの適用
                    showProgressView(PatternStringUtil.patternToString(getApplicationContext(),
                            R.string.synchronizing,
                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                    CommonExecutor.execute(new Runnable() {
                        @Override
                        public void run() {
                            Logger.d(TAG, "onResume Sync operationId : " + operationId);
                            //報告画面からすでに同期処理を行っているため、needSyncFlgチェックは除外
                            if (operationDto != null) {
                                // 同期処理後、直列処理で新着更新を行う。
                                singleSyncOperation(operationId, operationDto.reportType);

                                //「I/O 帳票使用」がYESのみ、カテゴリ一括動機実施
                                if (ABVDataCache.getInstance().serviceOption.isUnableIOReport()) {
                                    //同期中のインジケーター表示中には新着更新中のインジケーター表示できないので、チェックする。
                                    while (progressDialogHorizontalShowing()) {
                                        try {
                                            Thread.sleep(100);
                                        } catch (InterruptedException ie) {
                                            Logger.e(TAG, "sleep error = " + ie.getLocalizedMessage());
                                        }
                                    }
                                    //新着更新後、一括同期処理を行うため、インジケーター表示
                                    handler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            showProgressPopup(PatternStringUtil.patternToString(getApplicationContext(),
                                                    R.string.updating,
                                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                                        }
                                    });
                                    mAutoBatchSyncFlg = true;
                                    //表示作業数が１０個以上の場合、２秒待機してから新着更新を行う。１０個未満は１秒待機
                                    List<OperationDto> operationList = mListHelper.getOperationList();
                                    int delaySeconds = 1000;
                                    if (operationList.size() >= DELAY_2SECONDS_OPERATION_MAX_COUNT) {
                                        delaySeconds = 2000;
                                    }
                                    handler.postDelayed(new Runnable() {
                                        @Override
                                        public void run() {
                                            dataRefresh(true);
                                        }
                                    }, delaySeconds);

                                }
                            } else {
                                closeProgressPopup();
                                dataRefresh(true);
                            }

                        }
                    });
                }
                if (!activityResultFlg && operationId == -1) {
                    dataRefresh(true);
                }
            }
        }
        putUserPref(AppDefType.UserPrefKey.SYNC_TARGET_OPERATION_ID, -1L);
        activityResultFlg = false;

        configurationToolbarIcon();
    }

    // 検索ダイアログ表示
    private void showSearchDialog() {
        contentRefresher.stopRefresh();
        if (mSearchDialog == null) {
            mSearchDialog = new Dialog(this);
            mSearchDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            mSearchDialog.setCanceledOnTouchOutside(false);
            mSearchDialog.setContentView(R.layout.operation_search_dialog);
        }

        mStartDate = (TextView) mSearchDialog.findViewById(R.id.start_date);

        mEndDate = (TextView) mSearchDialog.findViewById(R.id.end_date);

        // 33
        mSearchTextView = (EditText) mSearchDialog.findViewById(R.id.operation_name);
        mSearchTextView.setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_ENTER) {
                    Logger.d("------------------------------------------------set key");
                    //キーボードのエンターキーを無効にする
                    return true;
                }
                return false;
            }
        });

        mStartDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDatePicker(mStartDate);
            }
        });

        mEndDate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDatePicker(mEndDate);
            }
        });

        // クリアボタン
        mSearchDialog.findViewById(R.id.btn_clear).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 初期化
                clearData();
            }
        });

        // 検索ボタン
        mSearchDialog.findViewById(R.id.btn_search).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                mSearchWord = StringUtil.toString(mSearchTextView.getText());
                mStartDateStr = StringUtil.toString(mStartDate.getText());
                mEndDateStr = StringUtil.toString(mEndDate.getText());

                refreshOperationList();
                mSearchDialog.dismiss();

                // リソースパターンの適用
                ABVToastUtil.showMakeText(OperationListActivity.this, String.format(PatternStringUtil.patternToString(getApplicationContext(),
                                                                                                R.string.operation_search_count,
                                                                                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), mListHelper.getOperationCount() + ""), Toast.LENGTH_SHORT);
            }
        });

        // 閉じるボタン
        mSearchDialog.findViewById(R.id.closeBtn).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                mSearchDialog.dismiss();
            }
        });
        if (mSearchDialog != null) {
            mSearchDialog.show();
        }
    }

    private void showDatePicker(final TextView text) {
        String textViewStr = text.getText().toString();
        Calendar calendar = Calendar.getInstance();
        if (!textViewStr.isEmpty()) {
            calendar.setTime(DateTimeUtil.toDate(textViewStr, DateTimeFormat.yyyyMMdd_slash));
        }
        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);

        //TODO layout変更 => DatePickerDialog.Theme_Holo_Light
        final DatePickerDialog dpd = new DatePickerDialog(this, android.R.style.Theme_Holo_Light_Dialog, new DatePickerDialog.OnDateSetListener() {

            @Override
            public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
                String date = String.format("%4d/%02d/%02d", year, monthOfYear + 1, dayOfMonth);
                if (dateValidation(text, date)) {
                    text.setText(date);
                }
            }

        }, year, month, day);
        dpd.setButton(DialogInterface.BUTTON_POSITIVE, getString(R.string.complete), dpd);
        dpd.setButton(DialogInterface.BUTTON_NEGATIVE, getResources().getString(R.string.cancel), dpd);
        dpd.setButton(DialogInterface.BUTTON_NEUTRAL, getString(R.string.clear), new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int whichButton) {
                text.setText(StringUtil.Empty);
            }
        });
        dpd.setCanceledOnTouchOutside(false);
        dpd.requestWindowFeature(Window.FEATURE_NO_TITLE);
        dpd.show();
    }

    private void clearData() {
        // 開始日の初期化
        if (mStartDate != null) {
            mStartDate.setText(StringUtil.Empty);
        }

        // 終了日の初期化
        if (mEndDate != null) {
            mEndDate.setText(StringUtil.Empty);
        }

        // 作業名の初期化
        if (mSearchTextView != null) {
            mSearchTextView.setText(StringUtil.Empty);
        }
    }

    // 開始日と終了日のバリデーション
    private boolean dateValidation(TextView textView, String targetDateStr) {
        boolean result = true;
        Date startDate = null;
        Date endDate = null;
        if (textView.equals(mStartDate)) {
            // 選択したTextViewを開始日と見做す
            if (!StringUtil.isNullOrEmpty(mEndDate.getText().toString())) {
                startDate = DateTimeUtil.toDate(targetDateStr, "UTC", DateTimeFormat.yyyyMMdd_hyphen);
                endDate = DateTimeUtil.toDate(mEndDate.getText().toString(), "UTC", DateTimeFormat.yyyyMMdd_hyphen);
            }
        } else {
            // 選択したTextViewが終了日と見做す
            if (!StringUtil.isNullOrEmpty(mStartDate.getText().toString())) {
                startDate = DateTimeUtil.toDate(mStartDate.getText().toString(), "UTC", DateTimeFormat.yyyyMMdd_hyphen);
                endDate = DateTimeUtil.toDate(targetDateStr, "UTC", DateTimeFormat.yyyyMMdd_hyphen);
            }
        }
        if (startDate != null && endDate != null) {
            if (startDate.after(endDate)) {
                // リソースパターンの適用
                ABVToastUtil.showMakeText(OperationListActivity.this, PatternStringUtil.patternToString(getApplicationContext(),
                                                                                R.string.msg_date_validation,
                                                                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), Toast.LENGTH_SHORT);
                result = false;
            }
        }
        return result;
    }

    public void startTaskDirectionOrReportView(OperationDto operationDto) {
        ContentDto contentDto = contentDao.getContent(operationDto.contentId);
        try {
            if (contentDto != null && contentDto.downloadedFlg) {
                String contentPath;
                if (operationDto.operationType == OperationType.LIST) {
                    contentPath = ABVEnvironment.getInstance().getTaskListDirName(ContentFileExtractor.getInstance().getContentCacheDirWithExtract(operationDto.contentId));
                } else if (operationDto.operationType == OperationType.PDF) {
                    contentPath = ABVEnvironment.getInstance().getTaskPdfDirName(ContentFileExtractor.getInstance().getContentCacheDirWithExtract(operationDto.contentId));
                } else {
                    contentPath = ABVEnvironment.getInstance().getPanoImageDirName(ContentFileExtractor.getInstance().getContentCacheDirWithExtract(operationDto.contentId));
                }

                // プロジェクトの指示/報告表示時、必要なJSONファイル作成
                mOperationLogic.createJsonForOpenABookCheckPano(operationDto.operationId, operationDto.contentId, contentPath);
                mOperationLogic.createJsonForOperationContent(operationDto.operationId, contentPath, operationDto.reportType == ReportType.RoutineTask);

                // サーバ作業後、対応必要
                StringBuffer path = new StringBuffer();
                path.append(contentPath);
                // #32926 作業報告画面改善 start
                path.append("/index.html?app=android");
                path.append("&report_type=" + operationDto.reportType);  // 作業報告タイプ : 0:報告 1:定期点検 2:報告(回答)
                path.append("&mobile_flg=" + (isNormalSize() ? "1" : "0"));  // ScreenType

                Logger.d(TAG, "path : " + path);
                // #32926 作業報告画面改善 end
                Intent intent = new Intent();
                intent.putExtra(ABookKeys.CONTENT_ID, operationDto.contentId);
                intent.putExtra(ABookKeys.OPERATION_ID, operationDto.operationId);
                intent.putExtra(Constant.ABookCheck.XWALK_OPEN_TYPE, Constant.XWalkOpenType.TASK_REPORT);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

                if(operationDto.operationType == OperationType.PDF) {
                    intent.putExtra("LINKURL", "file://" + path);
                    ActivityHandlingHelper.getInstance().checkContentActivity(operationDto.contentId, 0, intent);
				} else {
					ActivityHandlingHelper.getInstance().startHTMLWebActivity(this, intent, "file://" + path, operationDto.contentId, -1, -1, -1, -1, -1);
				}
            } else {
                Logger.w(TAG, "content is not download");
            }
        } catch (Exception e) {
            Logger.e(TAG, e);
            handleErrorMessageToast(ErrorCode.E107);
        }
    }

    @Override
    public void onDownloadingContentZip(final ContentZipDownloadNotification notification) {
        String errorCodeStr = "";
        if (isShowingBatchSync()) {
            if (notification.getError() != null) {
                Exception e = notification.getError();
                Logger.e(TAG, e);
                if (e instanceof AcmsException && ((AcmsException)e).getCode() != null) {
                    errorCodeStr = Integer.toString(((AcmsException)e).getHttpStatus());
                }
            }
        } else {
            super.onDownloadingContentZip(notification);
        }
        OperationContentDto operationContentDto = mOperationContentDao.getOperationContentForContentId(notification.getContentId());
        if (operationContentDto != null) {
            if (notification.downloadStatus == DownloadStatusType.Succeeded) {
                if (isShowingBatchSync()) {
                    // 一括同期からの同期処理
                    Logger.d(TAG, "[onDownloadingContentZip] batchOperationSync start");
                    batchSyncView.batchOperationSync();
                } else {
                    OperationDto operationDto = mOperationLogic.getOperation(operationContentDto.operationId);
                    singleSyncOperation(operationContentDto.operationId, operationDto.reportType, true);
                }
            } else if (notification.downloadStatus == DownloadStatusType.Failed || notification.downloadStatus == DownloadStatusType.Canceled || notification.downloadStatus == DownloadStatusType.Paused) {
                Logger.d(TAG, "syncOperation update is failed downloadStatus : " + notification.downloadStatus);
                if (isShowingBatchSync()) {
                    // 一括同期からのダウンロード失敗時、エラーメッセージ表示
                    OperationDto operationDto = mOperationLogic.getOperation(operationContentDto.operationId);
                    batchSyncView.showBatchSyncErrorAlert(operationDto, getString(R.string.msg_batch_sync_content_download_fail) + (StringUtil.isNullOrEmpty(errorCodeStr) ? "" : "(" + errorCodeStr + ")"));
                }
                closeProgressPopup();
                mQrCodeOperationId = null;
            }
        }
    }

    /**
     * プロジェクト同期処理
     * @param operationId
     * @param reportType
     * @param buttonEventFlag
     * @return errorメッセージ文字列
     */
    public String syncOperation(final long operationId, int reportType, boolean buttonEventFlag) {
        final StringBuilder errorMsg = new StringBuilder();
        Logger.i(TAG, "---sync start");
        try {
            //コンテンツダウンロード関連プログレスバー値設定
            progressDialogHorizontal.setProgress(20);
            final Callback progressCallback = new Callback() {
                @Override
                public Object callback(Object ret) {
                    final int progress = (int)ret;
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            progressDialogHorizontal.setProgress(progressDialogHorizontal.getProgress() + progress);
                        }
                    });
                    return null;
                }
            };

            // 報告送信
            mOperationLogic.sendTaskReportSendData(operationId, progressCallback);

            progressDialogHorizontal.setProgress(60);
            // 報告受信
            mOperationLastEditDate = receptionTaskData(operationId, progressCallback, buttonEventFlag, errorMsg);

            if (reportType == ReportType.RoutineTask) {
                if (buttonEventFlag) {
                    String dialogMsg = null;
                    // 定期点検プロジェクトの利用可能日付を取得
                    String avilableDateStr = mOperationLogic.getRoutineTaskOperationAvailableDateStr(operationId);
                    if (!StringUtil.isNullOrEmpty(avilableDateStr)) {
                        // 利用可能メッセージ
                        // リソースパターンの適用
                        dialogMsg = String.format(PatternStringUtil.patternToString(getApplicationContext(),
                                                    R.string.msg_routineTask_report_available_from,
                                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), avilableDateStr);
                    } else if (!mTaskReportDao.existsToDoRoutineTaskReportData(operationId)) {
                        // 作業データが存在しないメッセージ
                        dialogMsg = PatternStringUtil.patternToString(getApplicationContext(),
                                        R.string.msg_no_report_data,
                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0));
                    }
                    if (!StringUtil.isNullOrEmpty(dialogMsg)) {
                        errorMsg.append(dialogMsg);
                    }
                }
            }
            putUserPref(String.format(AppDefType.UserPrefKey.SYNCED_OPERATION_ID, operationId), DateTimeUtil.toString(DateTimeUtil.getCurrentSqlDate(), DateTimeFormat.yyyyMMddHHmmss_slash));
        } catch (AcmsException e) {
            //noinspection EnumSwitchStatementWhichMissesCases
            switch (e.getCode()) {
                case P_E_ACMS_P003:
                    // リソースパターンを適用
                    errorMsg.append(getString(PatternStringUtil.patternToInt(getApplicationContext(), R.string.P003, getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
                    break;
                case P_E_ACMS_P004:
                    errorMsg.append(getString(PatternStringUtil.patternToInt(getApplicationContext(), R.string.P004, getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
                    break;
                case P_E_ACMS_P005:
                    errorMsg.append(getString(PatternStringUtil.patternToInt(getApplicationContext(), R.string.P005, getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
                    break;
                case P_E_ACMS_P006:
                    errorMsg.append(getString(PatternStringUtil.patternToInt(getApplicationContext(), R.string.P006, getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
                    break;
                default:
                    Logger.e(TAG, "syncOperation", e);
                    errorMsg.append(ErrorMessage.getErrorMessage(this, ErrorMessage.getErrorCode(e)));
                    break;
            }
        } catch (Exception e) {
            Logger.e(TAG, e);
            errorMsg.append(ErrorMessage.getErrorMessage(this, ABVExceptionCode.C_E_SYSTEM_0001));
        } finally {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    // データの受信時、エラーキャッチのための変数を初期化
                    isSyncGetTaskFileError = false;
                    if (mOperationLastEditDate != null) {
                        Date operationLastSyncDate = DateTimeUtil.getCurrentDate();
                        mOperationLogic.finishedSyncOperation(operationId, mOperationLastEditDate, operationLastSyncDate);
                        progressDialogHorizontal.setProgress(100);
                    }
                    mOperationLastEditDate = null;
                    refreshOperationList();
                    closeProgressPopup();
                }
            });
            Logger.i(TAG, "---sync end");
        }
        return errorMsg.length() > 0 ? errorMsg.toString() : null;
    }

    public void onClickShowHelpView(View v) {
        showHelpViewDialog(Constant.HelpViewType.OperationListReporter);
    }
    /**
     * 360編集画面表示
     *
     * @param operationDto
     */
    public void startPanoEdit(OperationDto operationDto) {
        if (operationDto.contentId != null && operationDto.contentId != 0) {
            showProgressPopup();
            try {
                String baseUrl = ABVEnvironment.getInstance().acmsAddress + ABVDataCache.getInstance().getUrlPath() + "/shop/login/authByCheck/%s/%s";
                String url = String.format(baseUrl, ABVDataCache.getInstance().getMemberInfo().sid, operationDto.contentId);
                Intent intent = new Intent();
                intent.putExtra(ABookKeys.CONTENT_ID, operationDto.contentId);
                intent.putExtra(ABookKeys.OPERATION_ID, operationDto.operationId);
                intent.putExtra(Constant.ABookCheck.XWALK_OPEN_TYPE, Constant.XWalkOpenType.PANO_EDIT);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                ActivityHandlingHelper.getInstance().startHTMLWebActivity(OperationListActivity.this, intent, url, operationDto.contentId, -1, -1, -1, -1, -1);
            } catch (Exception e) {
                Logger.e(TAG, e);
                ErrorMessage.showErrorMessageToast(getApplicationContext(), ErrorCode.E107);
            } finally {
                closeProgressPopup();
            }
        }
    }

    /**
     * 作業データ受信
     * @param operationId 作業ID
     * @param progressCallback プログレスコールバック
     * @param buttonEventFlag ボタンタッチフラグ
     * @param errorMsg エラーメッセージ
     * @return
     * @throws NetworkDisconnectedException
     * @throws ABVException
     * @throws IOException
     * @throws InterruptedException
     * @throws NoSuchAlgorithmException
     * @throws ZipException
     */
    public Date receptionTaskData(long operationId, Callback progressCallback, boolean buttonEventFlag, StringBuilder errorMsg) throws NetworkDisconnectedException, ABVException, IOException, InterruptedException, NoSuchAlgorithmException, ZipException {
        GetOperationDataParameters param = new GetOperationDataParameters(ABVDataCache.getInstance().getMemberInfo().sid, operationId);
        OperationDto operationDto = mOperationLogic.getOperation(operationId);
        OperationContentDto operationContentDto = mOperationContentDao.getOperationMainContent(operationId);
        List<TaskDto> localTaskList = mTaskDao.selectAllTaskByOperationId(operationId);

        Date lastEditDate;

        OperationDataJSON json = AcmsClient.getInstance(ABVDataCache.getInstance().getUrlPath(), ABVEnvironment.getInstance().networkAdapter).getOpereationData(param);

        //プログレスを40%進行させるための計算
        int progress = 0;
        if (json.taskDtoList.size() != 0) {
            progress = 40 / json.taskDtoList.size();
        }

        boolean isRoutineTask = operationDto.reportType == ReportType.RoutineTask;


        for (TaskDto serverTaskDto : json.taskDtoList) {

            List<TaskReportDto> localTaskReportList = mTaskReportDao.getTaskReportListByTaskKey(serverTaskDto.taskKey);
            for (TaskReportDto localTaskReportDto : localTaskReportList) {
                if (!isExistsTaskReportInList(serverTaskDto.taskReportDtoList, localTaskReportDto, isRoutineTask)) {
                    if (isRoutineTask) {
                        mOperationLogic.deleteRoutineTaskReport(operationId, operationContentDto.contentId, localTaskReportDto);
                    } else {
                        // taskDtoが存在するとtaskReportLevel 0 (作業報告)が存在しないことはないので、報告（回答）のみチェックして削除
                        if (localTaskReportDto.taskReportLevel != TaskReportLevel.ReportType) {
                            // 作業報告のディレクトリ削除
                            mOperationLogic.deleteTaskFileData(operationId, operationContentDto.contentId, serverTaskDto.taskKey, localTaskReportDto.taskReportLevel);
                            mTaskReportDao.delete(localTaskReportDto);
                        }
                    }
                }
            }

            if (isExistsTaskInList(localTaskList, serverTaskDto)) {
                // 作業の報告更新
                mTaskDao.update(serverTaskDto);
                localTaskList.remove(serverTaskDto);
            } else {
                // 作業の報告登録
                mTaskDao.insert(serverTaskDto);
            }

            // サーバーからの情報で更新
            for (TaskReportDto serverTaskReportDto : serverTaskDto.taskReportDtoList) {
                String attachedFileName = serverTaskReportDto.attachedFileName;
                TaskReportDto localTaskReportDto;
                if (operationDto.reportType == ReportType.RoutineTask) {
                    localTaskReportDto = mTaskReportDao.getRoutineTaskReportUtc(serverTaskReportDto.taskKey, serverTaskReportDto.taskReportId, DateTimeUtil.toString(serverTaskReportDto.reportStartDate, DateTimeFormat.yyyyMMddHHmmss_hyphen));
                } else {
                    localTaskReportDto = mTaskReportDao.selectByTaskKey(serverTaskReportDto.taskKey, serverTaskReportDto.taskReportLevel);
                }
                if (localTaskReportDto != null && localTaskReportDto.localSavedFlg) {
                    // 一時保存フラグがtrueで定期点検且つ点検後修正不可の場合、添付ファイル（作業報告のディレクトリ）を削除して、localSavedFlgをfalseに変更
                    if (operationDto.reportType == ReportType.RoutineTask && operationDto.enableReportUpdate == Constant.EnableReportUpdate.NO) {
                        // 作業報告のディレクトリ削除
                        FileUtil.delete(ABVEnvironment.getInstance().getTempTaskDirPath(operationContentDto.contentId, localTaskReportDto.taskKey));
                        FileUtil.delete(ABVEnvironment.getInstance().getRoutineTaskReportDirFilePath(operationId, localTaskReportDto.taskKey, localTaskReportDto.taskReportId, DateTimeUtil.toString_yyyyMMddHHmmss_none(localTaskReportDto.reportStartDate)));
                        localTaskReportDto.localSavedFlg = false;
                    } else {
                        // 一時保存フラグがtureだと何もしない
                        continue;
                    }
                }

                if (operationDto.reportType == ReportType.RoutineTask) {
                    serverTaskReportDto.taskKey = serverTaskDto.taskKey;
                    try {
                        // 添付ファイルが存在する場合、取得して解凍する。
                        refreshRoutineTaskFile(operationId, operationContentDto.contentId, serverTaskDto.taskId, serverTaskDto.taskKey, serverTaskReportDto.taskReportId, serverTaskReportDto.taskReportInfoId, serverTaskReportDto.reportStartDate, attachedFileName);
                    } catch (Exception e) {
                        Logger.e(TAG, e);
                        // リソースパターンの適用
                        errorMsg.append(getString(PatternStringUtil.patternToInt(getApplicationContext(), R.string.msg_error_task_report_receiving_failed, getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
                        return null;
                    }

                    if (localTaskReportDto != null) {
                        // 報告データが存在すると作業報告を更新する
                        mOperationLogic.updateRoutineTaskReport(serverTaskDto.operationId, operationContentDto.contentId, serverTaskReportDto, false,  false, localTaskReportDto.localSavedFlg);
                    } else {
                        mOperationLogic.insertRoutineTaskReport(serverTaskDto.operationId, operationContentDto.contentId, serverTaskReportDto, false, false);
                    }

                } else {
                    JSONObject taskReportJson = null;
                    // 添付ファイルが存在する場合、取得して解凍する。
                    try {
                        refreshTaskFile(operationId, serverTaskReportDto.taskReportLevel, operationContentDto.contentId, serverTaskDto.taskId, serverTaskDto.taskKey, serverTaskReportDto.attachedFileName);
                    } catch (Exception e) {
                        Logger.e(TAG, e);
                        // リソースパターンの適用
                        errorMsg.append(getString(PatternStringUtil.patternToInt(getApplicationContext(), R.string.msg_error_task_report_receiving_failed, getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0))));
                        return null;
                    }
                    if (!serverTaskReportDto.jsonData.isEmpty()) {
                        taskReportJson = new JSONObject(serverTaskReportDto.jsonData);
                        if (serverTaskReportDto.taskReportLevel == TaskReportLevel.ReportType) {
                            taskReportJson.put(ABookKeys.TASK_STATUS, serverTaskDto.taskStatus);
                        }
                    }
                    if (localTaskReportDto == null) {
                        // 登録
                        mOperationLogic.insertTaskReport(
                                serverTaskDto.taskKey,
                                operationId,
                                operationContentDto.contentId,
                                serverTaskReportDto.taskReportLevel,
                                serverTaskReportDto.enableReport,
                                taskReportJson,
                                attachedFileName,
                                false,
                                false,
                                false,
                                serverTaskReportDto.getSendBackInfo(),
                                serverTaskReportDto.getLockInfo(),
                                serverTaskDto.taskStatus);
                    } else {
                        // 更新
                        // jsonDataが空で入る場合、taskReportJsonをnullで登録
                        mOperationLogic.updateTaskReport(
                                serverTaskDto.taskKey,
                                operationId,
                                operationContentDto.contentId,
                                serverTaskReportDto.taskReportLevel,
                                serverTaskReportDto.enableReport,
                                taskReportJson,
                                attachedFileName,
                                false,
                                false,
                                localTaskReportDto.localSavedFlg,
                                serverTaskReportDto.getSendBackInfo(),
                                serverTaskReportDto.getLockInfo(),
                                serverTaskReportDto.taskStatus
                        );
                    }
                }
            }

            progressCallback.callback(new Integer(progress));
        }
        // サーバーから取得した作業情報がローカルに存在しないので削除する
        for (TaskDto taskDto : localTaskList) {
            boolean localSaved = mTaskReportDao.isLocalSaved(taskDto.taskKey, 0, null);
            // 一時保存があったらそれは消さない
            if (!localSaved) {
                mOperationLogic.deleteTaskFileData(operationId, operationContentDto.contentId, taskDto.taskKey, TaskReportLevel.ReportType);
                mTaskDao.delete(taskDto);
            }
        }
        lastEditDate = json.lastEditDate;
        progressCallback.callback(new Integer(40));

        return lastEditDate;
    }

    /**
     * 添付ファイルが存在する場合、取得して解凍する。
     * @param operationId
     * @param taskReportLevel
     * @param contentId
     * @param taskId
     * @param taskKey
     * @param attachedFileName
     * @throws ABVException
     * @throws InterruptedException
     * @throws ZipException
     * @throws NoSuchAlgorithmException
     * @throws IOException
     */
    public void refreshTaskFile(final long operationId, final int taskReportLevel, long contentId, final long taskId, final String taskKey, final String attachedFileName) throws Exception {
        //　既存の添付ディレクトリ削除
        FileUtil.delete(ABVEnvironment.getInstance().getTempTaskDirPath(contentId, taskKey));

        String reportLocalAttachedFileName = mTaskReportDao.getTaskReportAttachedFileName(taskKey, taskReportLevel);
        if (attachedFileName != null && !attachedFileName.equals(reportLocalAttachedFileName)) {
            Logger.i(TAG, "[Get Task Report Files] operationId=%s, taskKey=%s, taskId=%s, attachedFileName=%s", operationId, taskKey, taskId, attachedFileName);
            // #32926 start
            FileUtil.delete(ABVEnvironment.getInstance().getOperationTaskReportLevelDirPath(operationId, taskKey, taskReportLevel));
            // #32926 end
            String outputFilePath = mOperationLogic.getTaskFile(operationId, taskKey, taskId, attachedFileName, taskReportLevel);
            ContentFileExtractor.getInstance().extractZipFile(contentId, outputFilePath, ABVEnvironment.getInstance().getOperationTaskReportLevelDirPath(operationId, taskKey, taskReportLevel),null, true);
        }
    }

    /**
     * 定期点検用ファイル更新
     * @param operationId
     * @param contentId
     * @param taskId
     * @param taskKey
     * @param taskReportId
     * @param reportStartDate
     * @param reportAttachedFileName
     * @throws ABVException
     * @throws InterruptedException
     * @throws ZipException
     * @throws NoSuchAlgorithmException
     * @throws IOException
     */
    public void refreshRoutineTaskFile(final long operationId, final long contentId, final long taskId, final String taskKey, final int taskReportId, final int taskReportInfoId, final Date reportStartDate, final String reportAttachedFileName) throws ABVException, InterruptedException, ZipException, NoSuchAlgorithmException, IOException {
        String reportStartDateHypn = DateTimeUtil.toString(reportStartDate, DateTimeFormat.yyyyMMddHHmmss_hyphen);
        final String reportStartDateNone = DateTimeUtil.toString_yyyyMMddHHmmss_none(reportStartDate);
        //　既存の添付ディレクトリ削除
        FileUtil.delete(ABVEnvironment.getInstance().getTempTaskDirPath(contentId, taskKey));

        String reportLocalAttachedFileName = mTaskReportDao.getRoutineTaskReportAttachedFileName(taskKey, taskReportId, reportStartDateHypn);
        boolean getReportFileFlg = !StringUtil.isNullOrEmpty(reportAttachedFileName) && !reportAttachedFileName.equals(reportLocalAttachedFileName);

        if (getReportFileFlg) {
            Logger.i(TAG, "[Get Task Report Files] operationId=%s, taskKey=%s, taskId=%s, attachedFileName=%s", operationId, taskKey, taskId, reportAttachedFileName);
            // #32926 start
            int taskReportLevel = 0;
            FileUtil.delete(ABVEnvironment.getInstance().getRoutineTaskReportDirFilePath(operationId, taskKey, taskReportId, reportStartDateNone));
            // #32926 end
            String outputFilePath = mOperationLogic.getRoutineTaskReportFile(operationId, taskKey, taskId, taskReportId, taskReportInfoId, reportStartDateNone, reportAttachedFileName);
            // #32926 start
            ContentFileExtractor.getInstance().extractZipFile(contentId, outputFilePath,
                    ABVEnvironment.getInstance().getRoutineTaskReportDirFilePath(operationId, taskKey, taskReportId, reportStartDateNone), null, true);
            // #32926 end
        }
    }

    /**
     * 360コンテンツ登録ダイアログ
     */
    public void showPanoEntryDialog(final OperationDto operationDto) {
        Logger.d(TAG, "showPanoEntryDialog");
        if (contentRefresher != null && contentRefresher.isRefreshing()) {
            // 新着更新処理が行っていれば、止める
            contentRefresher.stopRefresh();
        }
        if (mPanoEntryDialog == null) {
            mPanoEntryDialog = new Dialog(OperationListActivity.this);
            mPanoEntryDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            mPanoEntryDialog.setCanceledOnTouchOutside(false);
            mPanoEntryDialog.setContentView(R.layout.operation_pano_entry_dialog);
        }
        mPanoCotnentImageView = (ImageView) mPanoEntryDialog.findViewById(R.id.pano_image_view);
        mPanoContentNameTextView = (TextView) mPanoEntryDialog.findViewById(R.id.operation_name);

        mPanoContentNameTextView.setText(operationDto.operationName);
        mPanoCotnentImageView.setImageBitmap(null);
        FileUtil.delete(ABVEnvironment.getInstance().getCacheTempAttachedImageDirPath());

        // 閉じるボタン
        mPanoEntryDialog.findViewById(R.id.closeBtn).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                mPanoCotnentImageView.setImageBitmap(null);
                mSelectPanoContentUri = null;
                mPanoEntryDialog.dismiss();
                FileUtil.delete(ABVEnvironment.getInstance().getCacheTempAttachedImageDirPath());
            }
        });


        // 画像選択ボタン
        mPanoEntryDialog.findViewById(R.id.select_image).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                startCameraIntent(ABOOK_CHECK_OPERATION_PANO_CONTENT_IMAGE, "Camera", ABookKeys.IMAGE, false);
            }
        });


        // 登録ボタン
        mPanoEntryDialog.findViewById(R.id.btn_entry).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
                    ABVToastUtil.showMakeText(OperationListActivity.this, R.string.msg_network_offline, Toast.LENGTH_SHORT);
                    return;
                }
                if (mSelectPanoContentUri == null) {
                    ABVToastUtil.showMakeText(OperationListActivity.this, PatternStringUtil.patternToInt(getApplicationContext(),
                                                                                        R.string.msg_pano_image_no_selected,
                                                                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), Toast.LENGTH_SHORT);
                    return;
                }
                // リソースパターンの適用
                showProgressView(PatternStringUtil.patternToString(getApplicationContext(),
                                    R.string.msg_common_processing,
                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                CommonExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        boolean isError = true;
                        String[] projection = {MediaStore.MediaColumns.DATA};
                        Cursor cursor = getContentResolver().query(mSelectPanoContentUri, projection, null, null, null);

                        String scenePath = null;
                        if (mSelectPanoContentUri.toString().contains("file")) { //アプリ内に臨時保存した画像ファイル
                            scenePath = mSelectPanoContentUri.getPath();
                        } else {
                            if (cursor != null) {
                                if (cursor.moveToFirst()) {
                                    scenePath = cursor.getString(0);
                                }
                                cursor.close();
                            }

                        }
                        if (scenePath != null) {
                            File file = new File(scenePath);
                            isError = true;
                            try {
                                mOperationLogic.sendPanoContent(operationDto.operationId, operationDto.operationName, file);
                                isError = false;
                            } catch (ABVException e) {
                                //noroutineion EnumSwitchStatementWhichMissesCases
                                switch (e.getCode()) {
                                    case P_E_ACMS_P001:
                                        showSimpleAlertDialog(R.string.app_name,
                                                PatternStringUtil.patternToInt(getApplicationContext(),
                                                        R.string.P001,
                                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                                        break;
                                    case P_E_ACMS_P002:
                                        showSimpleAlertDialog(R.string.app_name,
                                                PatternStringUtil.patternToInt(getApplicationContext(),
                                                        R.string.P002,
                                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
                                        break;
                                    case S_E_ACMS_0500:
                                        handleErrorMessageToast(ABVExceptionCode.S_E_ACMS_0500);
                                        break;
                                    default:
                                        Logger.e(TAG, "PanoContent send error", e);
                                        handleErrorMessageToast(ErrorCode.E107);
                                        break;
                                }
                            } catch (Exception e) {
                                Logger.e(TAG, e);
                                ErrorMessage.showErrorMessageToast(OperationListActivity.this, ErrorCode.E107);
                            }
                        }
                        if (isError) {
                            closeProgressPopup();
                        } else {
                            handler.post(new Runnable() {
                                @Override
                                public void run() {
                                    progressDialogHorizontal.setProgress(20);
                                    mOperationLogic.setContentCreatingFlg(operationDto.operationId);
                                    refreshOperationList();
                                }
                            });

                            //10秒後に新着更新させる
                            handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    int progress = progressDialogHorizontal.getProgress();
                                    progressDialogHorizontal.setProgress(progress + 8);
                                    if (progress >= 100) {
                                        closeProgressPopup();
                                        mPanoEntryDialog.dismiss();
                                        mPanoCotnentImageView.setImageBitmap(null);
                                        dataRefresh(true);
                                    } else {
                                        handler.postDelayed(this, 1000);
                                    }
                                }
                            }, 1000);
                        }
                    }
                });
            }
        });

        if (mPanoEntryDialog != null) {
            mPanoEntryDialog.show();
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        activityResultFlg = true;
        Uri result = (intent == null || resultCode != RESULT_OK) ? null : intent.getData();
        if (requestCode == ABOOK_CHECK_OPERATION_PANO_CONTENT_IMAGE) {
            if (result != null) {
                mSelectPanoContentUri = result;
                try {
                    String[] projection = {MediaStore.MediaColumns.DATA};
                    Cursor cursor = getContentResolver().query(mSelectPanoContentUri, projection, null, null, null);
                    String photoFilePath = ABookCheckWebViewHelper.getInstance().contentSchemeUriToFilePath(cursor);
                    int rotationAngle = ABookCheckWebViewHelper.getInstance().rotateBitmapOrientation(photoFilePath);
                    if (rotationAngle != 0) {
                        mLocalFile = ABookCheckWebViewHelper.getInstance().rotateBitmapToImageFile(rotationAngle, photoFilePath, ABVEnvironment.getInstance().getCacheTempAttachedImageDirPath());
                        mSelectPanoContentUri = Uri.fromFile(mLocalFile);
                    }
                    if (mSelectPanoContentUri != null) {
                        InputStream stream = getContentResolver().openInputStream(mSelectPanoContentUri);
                        Bitmap bitmap = BitmapFactory.decodeStream(stream);
                        mPanoCotnentImageView.setImageBitmap(bitmap);
                    }

                } catch (FileNotFoundException e) {
                    Logger.e(TAG, "panoImageContent is not found", e);
                } catch (IOException e) {
                    Logger.e(TAG, "IOException = ", e);
                }
            }
        }

        // QRのアクティビティのリクエストコード判定する
        if (IntentIntegrator.REQUEST_CODE == requestCode){
            IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode,resultCode,intent);
            if (scanResult != null) {
                String url = scanResult.getContents();
                if (url == null) { //QRコードリーダー画面から「閉じる」ボタンタップ時
                    Logger.v(TAG, "Clicked Close Button.");
                    return;
                }
                //有効なスキームチェック
                if (url != null && url.startsWith(OPERATION_QRCODE_SCHEME)){
                    Uri operationUrl = Uri.parse(url);
                    String operationIdStr = operationUrl.getQueryParameter(QRCODE_OPERATION_ID);
                    if (operationIdStr == null) {
                        showErrorDialog(R.string.msg_qrcode_operation_not_found);
                        return;
                    } else {
                        long operationId = Long.parseLong(operationIdStr);
                        OperationDto operationDto = mOperationLogic.getOperation(operationId);
                        if (operationDto == null) {
                            showErrorDialog(R.string.msg_qrcode_operation_not_found);
                            return;
                        }
                        if (needAutoSync()) {
                            autoSyncOperationId(operationId);
                            return;
                        }
                        if (operationDto.needSyncFlg) {
                            //インターネット非接続時にはアラート表示
                            if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
                                ContentDto contentDto = contentDao.getContent(operationDto.contentId);
                                if (contentDto == null || !contentDto.downloadedFlg || contentDto.updatedFlg) {
                                    showErrorDialog(R.string.msg_qrcode_disconnect_content_download);
                                } else {
                                    openReportView(operationDto);
                                }
                                return;
                            }
                            mQrCodeOperationId = operationId;
                            startSyncOperation(operationDto);
                        } else {
                            openReportView(operationDto);
                        }
                    }
                } else {
                    showErrorDialog(R.string.msg_qrcode_not_operation_format);
                }
            }
        }
    }

    private void showOperationSelectDialog() {
        mOperationSelectDialog = new Dialog(OperationListActivity.this);
        mOperationSelectDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        mOperationSelectDialog.setCanceledOnTouchOutside(false);
        mOperationSelectDialog.setContentView(R.layout.operation_select_dialog);
        mOperationSelectListView = (ListView) mOperationSelectDialog.findViewById(R.id.lv_operation_select);

        mOperationSelectAdapter = new OperationSelectAdapter(OperationListActivity.this, mListHelper.getOperationList());
        mOperationSelectListView.setAdapter(mOperationSelectAdapter);

        mOperationSelectListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                OperationDto operationDto = mOperationSelectAdapter.getItem(position);
                showPushMessageSendDialog(operationDto);
                mOperationSelectDialog.dismiss();

            }
        });

        // リソースパターンを適用
        TextView operationSelect = (TextView) mOperationSelectDialog.findViewById(R.id.tv_toolbar_title);
        operationSelect.setText(PatternStringUtil.patternToInt(getApplicationContext(),
                                    R.string.operation_select,
                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));

        mOperationSelectDialog.findViewById(R.id.close_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mOperationSelectDialog.dismiss();
            }
        });

        mOperationSelectDialog.show();
    }



    /**
     * プッシュメッセージ送信ダイヤログ表示
     */
    private void showPushMessageSendDialog(final OperationDto operationDto) {
        mPushMessageSendDialog = new Dialog(OperationListActivity.this);
        mPushMessageSendDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        mPushMessageSendDialog.setCanceledOnTouchOutside(false);
        mPushMessageSendDialog.setContentView(R.layout.push_message_send_dialog);
        mFixPushMessageListView = (ListView) mPushMessageSendDialog.findViewById(R.id.listView);


        mPushMessageSendDialog.findViewById(R.id.back_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showOperationSelectDialog();
                mPushMessageSendDialog.dismiss();
            }
        });

        mPushMessageSendDialog.findViewById(R.id.close_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mPushMessageSendDialog.dismiss();
            }
        });

        mPushMessageSendDialog.findViewById(R.id.send_btn).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendPushMessageRequest(operationDto.operationId);
            }
        });

        RadioGroup searchTarget = (RadioGroup) mPushMessageSendDialog.findViewById(R.id.send_target_group);
        searchTarget.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                if (checkedId == R.id.in_gourp) {
                    mSendType = PushMessageSendType.InGroup;
                } else {
                    mSendType = PushMessageSendType.AllOperation;
                }
            }
        });

        mPushMessageSendDialog.findViewById(R.id.fix_push_message_layout).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showFixPushMessageView();
            }
        });

        TextView messageTitleTextView = (TextView) mPushMessageSendDialog.findViewById(R.id.message_title);
        // リソースパターンの適用
        messageTitleTextView.setText(PatternStringUtil.patternToString(getApplicationContext(),
                                        R.string.free_input,
                                        getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)) + " > ");

        TextView tvOperationName = (TextView) mPushMessageSendDialog.findViewById(R.id.operation_name);
        tvOperationName.setText(operationDto.operationName);

        mPushMessageSendDialog.show();
    }

    /**
     * プッシュメッセージ送信画面、定型文一覧画面切り替え
     * @param sendPushMessageViewFlg (true : プッシュメッセージ送信画面、false : 定型文一覧画面)
     */
    private void showSendPushMessgeView(boolean sendPushMessageViewFlg) {
        if (sendPushMessageViewFlg) {
            mFixPushMessageListView.setVisibility(View.GONE);
            mPushMessageSendDialog.findViewById(R.id.back_btn).setVisibility(View.GONE);

            mPushMessageSendDialog.findViewById(R.id.push_send_layout).setVisibility(View.VISIBLE);
            mPushMessageSendDialog.findViewById(R.id.close_btn).setVisibility(View.VISIBLE);
            EditText messageEditText = (EditText) mPushMessageSendDialog.findViewById(R.id.message);
            KeyboardUtils.show(OperationListActivity.this, messageEditText);
        } else {
            mFixPushMessageListView.setVisibility(View.VISIBLE);
            mPushMessageSendDialog.findViewById(R.id.back_btn).setVisibility(View.VISIBLE);

            mPushMessageSendDialog.findViewById(R.id.push_send_layout).setVisibility(View.GONE);
            mPushMessageSendDialog.findViewById(R.id.close_btn).setVisibility(View.GONE);
        }
    }

    /**
     * プッシュメッセージ送信依頼
     */
    private void sendPushMessageRequest(long operationId) {
        if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            ABVToastUtil.showMakeText(OperationListActivity.this, R.string.request_network_connection, Toast.LENGTH_SHORT);
            return;
        }
        //文字列チェック
        EditText messageEditText = (EditText) mPushMessageSendDialog.findViewById(R.id.message);
        String message = messageEditText.getText().toString();

        String checkMessage = message.replace(" ", "");
        if (checkMessage.length() == 0) {
            // リソースパターンの適用
            ABVToastUtil.showMakeText(OperationListActivity.this, PatternStringUtil.patternToString(getApplicationContext(),
                                                                            R.string.push_message_input_null,
                                                                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), Toast.LENGTH_SHORT);
            return;
        }
        byte[] messageByte = message.getBytes(StandardCharsets.UTF_8);
        if (messageByte.length >= 207) {
            // リソースパターンの適用
            ABVToastUtil.showMakeText(OperationListActivity.this, PatternStringUtil.patternToString(getApplicationContext(),
                                                                            R.string.push_message_input_over,
                                                                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), Toast.LENGTH_SHORT);
            return;
        }

        // リソースパターンの適用
        ProgressDialogHelper.showProgressPopup(OperationListActivity.this, true, PatternStringUtil.patternToString(getApplicationContext(),
                                                                                                    R.string.file_initialization,
                                                                                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
        try {
            boolean result = mPushMessageLogic.sendPushMessageRequest(mSendType, message, operationId);
            if (result) {
                mPushMessageSendDialog.dismiss();
                // リソースパターンの適用
                ABVToastUtil.showMakeText(OperationListActivity.this, PatternStringUtil.patternToString(getApplicationContext(),
                                                                                R.string.push_message_send_success,
                                                                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), Toast.LENGTH_SHORT);
            } else {
                // リソースパターンの適用
                ABVToastUtil.showMakeText(OperationListActivity.this, PatternStringUtil.patternToString(getApplicationContext(),
                                                                                R.string.push_message_send_fail,
                                                                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), Toast.LENGTH_SHORT);
            }
        } catch (Exception e) {
            Logger.e(TAG, e);
            // リソースパターンの適用
            ABVToastUtil.showMakeText(OperationListActivity.this, PatternStringUtil.patternToString(getApplicationContext(),
                                                                            R.string.push_message_send_fail,
                                                                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), Toast.LENGTH_SHORT);
        } finally {
            ProgressDialogHelper.closeProgressPopup();
        }
    }

    private void showFixPushMessageView() {
        if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            ABVToastUtil.showMakeText(OperationListActivity.this, R.string.request_network_connection, Toast.LENGTH_SHORT);
            return;
        }
        EditText messageEditText = (EditText) mPushMessageSendDialog.findViewById(R.id.message);
        KeyboardUtils.hide(OperationListActivity.this, messageEditText);

        // リソースパターンの適用
        ProgressDialogHelper.showProgressPopup(OperationListActivity.this, true, PatternStringUtil.patternToString(getApplicationContext(),
                                                                                                    R.string.file_initialization,
                                                                                                    getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
        try {
            List<FixPushMessageDto> fixPushMessageList = mPushMessageLogic.getFixPushMessage();
            FixPushMessageDto dto = new FixPushMessageDto();
            // リソースパターンの適用
            dto.name = PatternStringUtil.patternToString(getApplicationContext(),
                            R.string.free_input,
                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0));
            fixPushMessageList.add(0, dto);
            mFixPushMessageListView.setAdapter(new FixPushMessageAdapter(OperationListActivity.this, fixPushMessageList, mSelectedFixPuchMessagePosition));
            mFixPushMessageListView.invalidate();
            mFixPushMessageListView.setClickable(true);
            mFixPushMessageListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    mSelectedFixPuchMessagePosition = position;
                    FixPushMessageDto item = (FixPushMessageDto)parent.getItemAtPosition(position);

                    TextView messageTitleTextView = (TextView) mPushMessageSendDialog.findViewById(R.id.message_title);
                    messageTitleTextView.setText(item.name + " > ");

                    EditText messageEditText = (EditText) mPushMessageSendDialog.findViewById(R.id.message);
                    messageEditText.setText(item.value);
                    messageEditText.setSelection(messageEditText.getText().length());

                    showSendPushMessgeView(true);
                }
            });
            showSendPushMessgeView(false);
        } catch (Exception e) {
            Logger.e(TAG, e);
            // リソースパターンの適用
            ABVToastUtil.showMakeText(OperationListActivity.this, PatternStringUtil.patternToString(getApplicationContext(),
                                                                            R.string.respons_fix_push_message_fail,
                                                                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)), Toast.LENGTH_SHORT);
        } finally {
            ProgressDialogHelper.closeProgressPopup();
        }
    }

    /**
     * listDtoの中に第2引数のdtoが存在するかチェックメソッド
     * @param listDto　リストDto
     * @param dto　ターゲットDto
     * @return
     */
    private boolean isExistsTaskInList(List<TaskDto> listDto, TaskDto dto) {
        for (TaskDto lDto : listDto) {
            if (lDto.taskKey.equals(dto.taskKey)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 報告存在チェック
     * @param listDto
     * @param rDto
     * @return
     */
    private boolean isExistsTaskReportInList(List<TaskReportDto> listDto, TaskReportDto rDto, boolean isRoutineTask) {
        for (TaskReportDto lDto : listDto) {
            if (isRoutineTask) {
                // 定期点検の場合、taskKey,taskReportId,reportStartDateで判定
                if (lDto.taskKey.equals(rDto.taskKey) &&
                        lDto.taskReportId == rDto.taskReportId  &&
                        lDto.reportStartDate.equals(rDto.reportStartDate)) {
                    return true;
                }
            } else {
                // taskKeyと作業報告階層で判定
                if (lDto.taskKey.equals(rDto.taskKey) &&
                        lDto.taskReportLevel == rDto.taskReportLevel) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 作業報告画面に移動
     * @param operationDto
     */
    public void openReportView(OperationDto operationDto) {
        if (ActivityHandlingHelper.getInstance().isMeetingConnected()) {
            return;
        }
        // 新着更新を止める
        contentRefresher.stopRefresh();
        startTaskDirectionOrReportView(operationDto);
    }

    /**
     * 同期処理
     * @param operationDto
     */
    public void startSyncOperation(final OperationDto operationDto) {
        //ネットワークチェック
        if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            ABVToastUtil.showMakeText(OperationListActivity.this, R.string.request_network_connection, Toast.LENGTH_SHORT);
            return;
        }
        //新着更新中
        if (contentRefresher.isRefreshing()) {
            mQrCodeOperationId = null;
            return;
        }
        // リソースパターンの適用
        showProgressView(PatternStringUtil.patternToString(getApplicationContext(),
                            R.string.synchronizing,
                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
        CommonExecutor.execute(new Runnable() {
            @Override
            public void run() {
                Logger.i(TAG, "[syncOperation] operationId=%s, contentId=%s", operationDto.operationId, operationDto.contentId);
                // コンテンツダウンロード
                ContentDto contentDto = contentDao.getContent(operationDto.contentId);
                if (contentDto == null || !contentDto.downloadedFlg || contentDto.updatedFlg) {
                    contentDownload(operationDto.contentId, false);
                } else {
                    singleSyncOperation(operationDto.operationId, operationDto.reportType, true);
                }
            }
        });
    }

    /**
     * リストビュー用のプルダウンで新着更新処理
     * @param refreshView
     */
    public void pullToListViewRefresh(PullToRefreshBase<ListView> refreshView) {
        refreshBaseView = refreshView;

        if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            showDisConnectNetworkDialog();
            return;
        }
        long lastUpdateTime = PreferenceUtil.getUserPref(getApplicationContext(), AppDefType.UserPrefKey.LAST_UPDATE_TIME, 0L);
        if (lastUpdateTime > 0) {
            String lastUpdateTimeLabel = null;
            String strUpdateTime = DateTimeUtil.toString(new Date(lastUpdateTime), DateTimeFormat.yyyyMMddHHmmss_slash);
            // リソースパターンの適用
            String formatStr = PatternStringUtil.patternToString(getApplicationContext(),
                                R.string.recent_update_date,
                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0));
            lastUpdateTimeLabel = String.format(formatStr, strUpdateTime);

            // Update the LastUpdatedLabel
            if (lastUpdateTimeLabel != null) {
                refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(lastUpdateTimeLabel);
            }
        }
        if (needAutoSync()) {
            autoSyncOperation();
            return;
        }
        CommonExecutor.execute(new Runnable() {
            @Override
            public void run() {
                if (!contentRefresher.isRefreshing()) {
                    dataRefresh(false);
                }
            }
        });

    }

    /**
     * パンネルビュー用のプルダウンで新着更新処理
     * @param refreshView
     */
    public void pullToGridViewRefresh(PullToRefreshBase<GridView> refreshView) {
        // 完了通知のため、ビューをメンバー変数で管理する
        refreshBaseView = refreshView;
        if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            showDisConnectNetworkDialog();
            return;
        }
        long lastUpdateTime = PreferenceUtil.getUserPref(getApplicationContext(), AppDefType.UserPrefKey.LAST_UPDATE_TIME, 0L);
        if (lastUpdateTime > 0) {
            String lastUpdateTimeLabel = null;
            String strUpdateTime = DateTimeUtil.toString(new Date(lastUpdateTime), DateTimeFormat.yyyyMMddHHmmss_slash);
            // リソースパターンの適用
            String formatStr = PatternStringUtil.patternToString(getApplicationContext(),
                                R.string.recent_update_date,
                                getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0));
            lastUpdateTimeLabel = String.format(formatStr, strUpdateTime);

            // Update the LastUpdatedLabel
            if (lastUpdateTimeLabel != null) {
                refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(lastUpdateTimeLabel);
            }
        }
        if (needAutoSync()) {
            autoSyncOperation();
            return;
        }
        CommonExecutor.execute(new Runnable() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        if (!contentRefresher.isRefreshing()) {
                            dataRefresh(false);
                        }
                    }
                });
            }
        });
    }

    /**
     * 並べ替え画面表示
     *
     * @param anchor
     */
    public void onClickOperationFilterList(final View anchor) {
        Logger.d(TAG, "onClickShowContentContainerList start");
        final ABVPopupListWindow popup = new ABVPopupListWindow(this, R.layout.popup_simple_list);
        popup.setTitle(getRString(R.string.filter));
        popup.setWidth(getRDimensionSize(R.dimen.popup_size_xlarge));

        // 表示するコンテンツタイプのリストを作成
        List<String> members =  Arrays.asList(getRStringArray(R.array.operation_report_types));
        for (int i = 0; i < members.size(); i++) {
            int rId = getResources().getIdentifier(members.get(i), "string", getPackageName());
            // リソースパターンの適用
            members.set(i, PatternStringUtil.patternToString(getApplicationContext(),
                            rId,
                            getUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, 0)));
        }
        ArrayList<Integer> selectedOperationReportTypes = getOperationReportTypeList(false);

        ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.item_checked_list, members);
        popup.setListViewAdapter(adapter);
        final ListView listView = popup.getListView();
        listView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
        for (int i = 0; i < mAllOperationReportTypes.size(); i++) {
            for (Integer id : selectedOperationReportTypes) {
                if (id.equals(mAllOperationReportTypes.get(i))) {
                    listView.setItemChecked(i, true);
                }
            }
        }


        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long cid) {
                // 並び替えの要素タップイベント
                SparseBooleanArray checkedItemPositions = popup.getListView().getCheckedItemPositions();

                ArrayList<Integer> selectedOperationReportTypeIds = new ArrayList<>();
                for (int i = 0; i < checkedItemPositions.size(); i++) {
                    if (checkedItemPositions.valueAt(i)) {
                        selectedOperationReportTypeIds.add(mAllOperationReportTypes.get(checkedItemPositions.keyAt(i)));
                    }
                }

                if (selectedOperationReportTypeIds.size() > 0) {
                    getABVUIDataCache().setOperationReportTypes(selectedOperationReportTypeIds);
                    setOperationListView();
                } else {
                    ((CheckedTextView)view).setChecked(true);
                    listView.getCheckedItemPositions().put(position, true);
                }
            }
        });
        listView.invalidate();
        popup.showAsDropDown(anchor);
    }

    /**
     * フィルター（報告タイプ）の項目取得
     * @param isAll フィルターの全ての項目を取得するか、チェックのみ取得するか判定フラグ
     * @return
     */
    private ArrayList<Integer> getOperationReportTypeList(boolean isAll) {
        ArrayList<Integer> operationReportTypes = new ArrayList<>();
        if (isAll) {
            operationReportTypes.add(ReportType.Report);
            operationReportTypes.add(ReportType.RoutineTask);
            operationReportTypes.add(ReportType.ReportReply);
        } else {
            operationReportTypes = getABVUIDataCache().getOperationReportTypes();
        }
        return operationReportTypes;
    }

    // ログイン成功した後、新着更新時の「ContentVersion」APIからリソースパターンを取得し、ローカルに保存する。
    private void setResourcePattern() {
        Logger.d(TAG, "ABVEnvironment.getInstance().resourcePatternType : " + ABVEnvironment.getInstance().resourcePatternType);
        putUserPref(AppDefType.UserPrefKey.RESOURCE_PATTERN_TYPE, ABVEnvironment.getInstance().resourcePatternType);
    }

    /**
     * フィルターの選択があるか判定して、画像を変更
     */
    private void checkSelectedFilterType() {
        List<Integer> defaultTypeList = getOperationReportTypeList(true);
        ArrayList<Integer> selectedOperationReportTypes = getOperationReportTypeList(false);
        ImageButton imgBtn = (ImageButton) findViewById(R.id.icon_filter);
        if (defaultTypeList.size() == selectedOperationReportTypes.size()) {
            imgBtn.setImageDrawable(getRDrawable(R.drawable.ic_filter));
        } else {
            imgBtn.setImageDrawable(getRDrawable(R.drawable.ic_filter_selected));
        }
    }

    private void setMasterDataFetchDate() {
        Logger.d(TAG, "ABVDataCache.getInstance().tempMasterDataFetchDate : " + ABVDataCache.getInstance().tempMasterDataFetchDate);
        putUserPref(AppDefType.UserPrefKey.MASTER_DATA_FETCH_DATE, ABVDataCache.getInstance().tempMasterDataFetchDate);
    }

    // 全て・カテゴリ選択画面(スマートフォン)
    public void onClickGroupLocationByNormalSize(View view) {
        final ABVListDialog dialog = new ABVListDialog(this);
        // 外側タップしてもダイアログ画面が閉じられないように設定
        final ArrayAdapter<String> adapter = new ArrayAdapter<>(this, R.layout.item_dialog_list, Arrays.asList(getRStringArray(R.array.category_types)));
        dialog.setTitle(getRString(R.string.category_list));
        dialog.setListViewAdapter(adapter);
        dialog.setCanceledOnTouchOutside(false);

        // 閉じるボタン
        dialog.setRightItemOnClickListener(R.drawable.ic_operation_close, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        dialog.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // ポップアップ再表示
                dialog.dismiss();
                setOperationLocation(id);
            }
        });

        if (isNormalSize()) {
            dialog.showHalfSize();
        } else {
            dialog.show();
        }
    }

    /**
     * カテゴリ選択した内容で設定・表示する
     * @param type 0 : 全て 1: カテゴリ
     */
    private void setOperationLocation(long type) {
        Logger.d(TAG, "setOperationLocation type :" + type);
        int localType = getABVUIDataCache().getOperationGroupMasterMode();

        // loadFlgがtrueの場合のみ、タイプを保存して画面を再作成する
        if (localType != type) {
            // typeの値をxmlに書き込み
            getABVUIDataCache().setOperationGroupMasterMode((int) type);
            // プログレスバー
            showProgressPopup();
            setOperationListView();
        }

        if (getABVUIDataCache().getOperationGroupMasterMode() == OperationLocationType.CATEGORY) {
            //作業種別モードの場合は、作業種別選択ダイアログ画面を表示
            showOperationGroupMasterDialog(true);
        }
    }

    /**
     * 作業種別の選択のダイアログ画面表示
     * @param isInit 初期表示
     */
    public void showOperationGroupMasterDialog(boolean isInit) {
        if (isInit || operationCountMap == null) {
            // 最後の階層レベルを取得
            Integer lastLevel = mOperationGroupMasterLogic.getLastGroupLevel();
            operationCountMap = new HashMap<Integer, Integer>();
            // 作業種別毎に作業数をMapにセット
            mOperationGroupMasterLogic.getAllOperationCount(lastLevel, operationCountMap);
        }
        // 既にダイアログが存在するか、開いた状態である場合は何もしない
        if (mShowDialog != null && mShowDialog.isShowing()) {
            return;
        }
        final ABVListDialog dialog = new ABVListDialog(this);
        // 外側タップしてもダイアログ画面が閉じられないように設定
        dialog.setCanceledOnTouchOutside(false);
        mShowDialog = dialog;
        OperationGroupMasterListHelper helper = (OperationGroupMasterListHelper) mListHelper;
        ArrayList<String> groupNames = new ArrayList<>();

        // 直下の作業種別リスト情報を取得
        final List<OperationGroupMasterDto> operationGroupMasterDtoList = helper.getChildList();

        dialog.setTitle(helper.getPeekName(), R.drawable.ic_title_group_operation);

        // 閉じるボタン
        dialog.setRightItemOnClickListener(R.drawable.ic_operation_close, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
            }
        });

        boolean[] haveChildFlags = new boolean[operationGroupMasterDtoList.size()];
        int[] operationCounts = new int[operationGroupMasterDtoList.size()];
        int i = 0;
        for (OperationGroupMasterDto dto : operationGroupMasterDtoList) {
            int operationGroupMasterId = dto.operationGroupMasterId;
            groupNames.add(dto.operationGroupMasterName);
            // 下位階層があるか否かチェック
            haveChildFlags[i] = helper.getChildList(operationGroupMasterId).size() > 0;
            // 子グループも含めて作業種別に紐づく作業数
            operationCounts[i] = operationCountMap.get(operationGroupMasterId);
            i++;
        }

        final HierarchyOperationGroupListAdapter adapter = new HierarchyOperationGroupListAdapter(this, groupNames, haveChildFlags, operationCounts);

        // 上位階層がある場合、上位階層に戻るボタンを追加
        if (helper.getStackSize() > 1) {
            dialog.setListViewAdapter(adapter);
            String backToName = helper.getPrePeekName();
            // スマートフォン端末で20文字を超えた場合、20文字まで切り落として後ろに...をつけて表示
            if (isNormalSize() && backToName.length() > 20) {
                backToName = backToName.substring(0, 20) + "...";
            }
            dialog.setHeaderItemOnClickListener(backToName, new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    OperationGroupMasterListHelper helper = (OperationGroupMasterListHelper) mListHelper;
                    helper.popList(1, true);
                    // ポップアップ再表示
                    dialog.dismiss();
                    showOperationGroupMasterDialog(false);
                }
            });
        } else {
            dialog.setListViewAdapter(adapter);
        }

        // 直下階層の要素をクリックイベント
        dialog.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                OperationGroupMasterDto operationGroupMasterDto = operationGroupMasterDtoList.get(position);
                OperationGroupMasterListHelper helper = (OperationGroupMasterListHelper) mListHelper;
                helper.pushList(operationGroupMasterDto);
                // ポップアップ再表示
                dialog.dismiss();
                showOperationGroupMasterDialog(false);
            }
        });

        // リストが空の時表示するテキストを設定
        dialog.setListEmptyText(getString(R.string.no_child));
        if (isNormalSize()) {
            dialog.showHalfSize();
        } else {
            dialog.show();
        }
    }

    /**
     * 作業種別ID取得
     * @return
     */
    public int getOperationGroupMasterId() {
        return getABVUIDataCache().getOperationGroupMasterId();
    }

    /**
     * 作業種別選択画面を閉じる処理
     */
    public void closeOperationGroupMasterDialog() {
        if (mShowDialog != null && mShowDialog.isShowing()) {
            mShowDialog.dismiss();
        }
    }

    /**
     * ソート順取得（デフォルト：１(作業期間が新しい順)）
     * @return
     */
    public int getSortCondition() {
        return getABVUIDataCache().getSortCondition();
    }

    /**
     * 開いた作業種別ID保存
     * @param operationGroupMasterId
     */
    public void setOperationGroupMasterId(int operationGroupMasterId) {
        getABVUIDataCache().setOperationGroupMasterId(operationGroupMasterId);
    }

    /**
     * operationListHelperに通常か作業種別のhelperをセット
     * @return
     */
    private OperationListHelper getListHelper() {
        OperationListHelper operationListHelper;
        if (mOperationGroupMasterServiceOperationFlg && getABVUIDataCache().getOperationGroupMasterMode() == OperationLocationType.CATEGORY) {
            operationListHelper = new OperationGroupMasterListHelper(this);
        } else {
            operationListHelper = new HomeOperationListHelper(this);
        }
        return operationListHelper;
    }
    // カテゴリのアイコンイメージ設定
    private void setCategoryImage(boolean isCategory) {
        mCategoryLocationButton.setImageResource(isCategory ? R.drawable.ic_category_on : R.drawable.ic_category_off);
    }
    // 検索ワードのクリア
    private void clearSearch() {
        mSearchWord = null;
        mStartDateStr = null;
        mEndDateStr = null;
        clearData();
    }
    // 検索済みかどうかチェック
    private boolean isSearched() {
        return !(StringUtil.isNullOrEmpty(mSearchWord) && StringUtil.isNullOrEmpty(mStartDateStr) && StringUtil.isNullOrEmpty(mEndDateStr));
    }

    /**
     * 全て・カテゴリ選択画面(タブレット)
     *
     * @param anchor
     */
    public void onClickGroupLocationByTablet(final View anchor) {
        Logger.d(TAG, "onClickGroupLocationByTablet start");
        final ABVPopupListWindow popup = new ABVPopupListWindow(this, R.layout.popup_simple_list);
        popup.setTitle(getRString(R.string.category_list));
        popup.setWidth(getRDimensionSize(R.dimen.popup_size_large));

        // 表示するコンテンツタイプのリストを作成
        ListView listView = popup.getListView();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.item_dialog_list, Arrays.asList(getRStringArray(R.array.category_types)));

        popup.setListViewAdapter(adapter);

        popup.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                popup.dismiss();
                setOperationLocation(id);
            }
        });
        if (anchor == null) {
            // 呼び出したViewが存在しない場合、真ん中に表示する
            popup.showAtLocation(getWindow().getDecorView().findViewById(android.R.id.content), Gravity.CENTER, 0,0);
        } else {
            popup.showAsDropDown(anchor);
        }
    }

    /**
     * カテゴリの一括同期ダイアログ表示
     */
    private void showBatchSyncDialog() {
        ABookAlertDialog dialog = AlertDialogUtil.createABookAlertDialog(this);
        dialog.setTitle(getString(R.string.batch_sync));
        dialog.setMessage(getString(R.string.msg_confirm_batch_sync));
        dialog.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                // 一括同期開始
                List<OperationDto> operationDtoList = mOperationDao.getNeedSyncOperationByGroupMasterId(getABVUIDataCache().getOperationGroupMasterId());
                categoryBatchSync(operationDtoList);
            }
        });
        dialog.setNegativeButton(R.string.cancel,  new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        if (mAlertDialog != null && this.mAlertDialog.isShowing()) {
            mAlertDialog.dismiss();
        }
        this.mAlertDialog = dialog;
        mAlertDialog.show();
    }

    /**
     * カテゴリの一括同期ボタン
     * @param operationDtoList 同期する作業情報配列
     */
    public void categoryBatchSync(List<OperationDto> operationDtoList) {
        Logger.i(TAG, "---batch sync start");
        // ネットワーク通信チェック
        if (!ABVEnvironment.getInstance().networkAdapter.isNetworkConnected()) {
            showSimpleAlertDialog(getString(R.string.app_name), getString(R.string.request_network_connection));
            return;
        }
        // 作業リストをスタックにセット
        Stack<OperationDto> operationDtoStack = new Stack<OperationDto>();
        operationDtoStack.addAll(operationDtoList);

        // 一括同期を設定
        batchSyncView = new ABVBatchSyncView(this);

        // batchSyncViewにスタックをセットして表示
        batchSyncView.setStack(operationDtoStack);
        batchSyncView.show();

        // 一括同期処理
        CommonExecutor.execute(new Runnable() {
            @Override
            public void run() {
                batchSyncView.batchOperationSyncForCheckDonwload();
            }
        });
    }
    /**
     * 一括同期の活性化・非活性化チェック
     */
    public void checkBatchNeedSyncButton(Integer operationGroupMasterId) {
        if (mOperationDao.hasNeedSyncOperationByGroupMasterId(operationGroupMasterId)) {
            // 選択したカテゴリ一覧でneedSyncFlgがtrueの作業が存在すれば、活性化する
            mOperationBatchSyncButton.setEnabled(true);
        } else {
            // 一括同期ボタンを非活性化する
            mOperationBatchSyncButton.setEnabled(false);
        }
    }
    // 作業の自動同期処理(onresumeで呼ばれる同期処理)
    public void singleSyncOperation(final long operationId, int operationReportType) {
        singleSyncOperation(operationId, operationReportType, false);
    }
    /**
     * 作業同期処理(単一)
     * @param operationId
     * @param operationReportType
     */
    public void singleSyncOperation(final long operationId, int operationReportType, boolean buttonEventFlg) {
        String errorMessage = syncOperation(operationId, operationReportType, buttonEventFlg);
        if (errorMessage != null) {
            closeProgressPopup();
            // エラーメッセージ表示
            showSimpleAlertDialog(getString(R.string.app_name), errorMessage);
        } else {
            if (mQrCodeOperationId != null) {
                if (mQrCodeOperationId == operationId) {
                    openReportView(mOperationLogic.getOperation(mQrCodeOperationId));
                    mQrCodeOperationId = null;
                }
            }
        }
    }
    /**
     * 作業用コンテンツダウンロード時、ダウンロードかダウンロード再開か判定して行う。
     * @param contentDto
     * @return
     */
    public boolean operationContentDownload(final ContentDto contentDto) {
        if (contentDto.isDownloadPaused()) {
            // ダウンロード途中で通信が切れた場合、一時停止のステータスに変更になるため、再開させる
            try {
                contentDownloader.resume(contentDto.contentId);
            } catch (Exception e) {
                Logger.e(TAG, "downloadContent failed. contentId=" + contentDto.contentId, e);
                return false;
            }
        } else {
            // ダウンロード
            return contentDownload(contentDto.contentId, false, false);
        }
        return true;
    }

    /**
     * 権限チェックし、QRコードリーダー画面を表示
     */
    private void showQrCodeReaderActivity() {
        //カメラパーミッションチェック
        ABookPermissionHelper helper = new ABookPermissionHelper(this, Constant.ABookPermissionType.Camera, null);
        if (helper.checkMultiPermissions(true)) {
            IntentIntegrator integrator = new IntentIntegrator(OperationListActivity.this);
            if (isNormalSize() == false) {
                integrator.setCaptureActivity(CaptureQRCodeActivityDialog.class);
            } else {
                integrator.setCaptureActivity(CaptureQRCodeActivity.class);
            }
            integrator.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE_TYPES);
            integrator.setPrompt("");
            integrator.setOrientationLocked(true);
            integrator.initiateScan();
        } else {
            Logger.w(TAG,"Camera Permission  false");
        }
    }

    private boolean isAutoSync() {
        return PreferenceUtil.get(getApplicationContext(), AppDefType.UserPrefKey.OPERATION_AUTO_SYNC, false);
    }
    public boolean needAutoSync() {
        return (isAutoSync() && ABVEnvironment.getInstance().networkAdapter.isNetworkConnected());
    }

    /**
     * Run refresh data and batch sync if need
     */
    public void autoSyncOperation() {
        if (mAutoSyncingFlg) {
            return;
        }
        mAutoSyncingFlg = true;
        showProgressPopup(getResources().getString(R.string.updating));
        CommonExecutor.execute(new Runnable() {
            @Override
            public void run() {
                dataRefresh(false);
                if (!contentRefresher.isRefreshing()) {
                    autoSyncOperationDone(false);
                }
            }
        });
    }

    /**
     * Auto sync and open operation if success
     * @param operationId
     */
    public void autoSyncOperationId(Long operationId) {
        mAutoSyncOpenOperationId = operationId;
        autoSyncOperation();
    }

    /**
     * Auto sync done
     * @param isSuccess
     */
    public void autoSyncOperationDone(boolean isSuccess) {
        mAutoSyncingFlg = false;
        closeProgressPopup();
        if (isSuccess) {
            if (mAutoSyncOpenOperationId != null) {
                OperationDto operationDto = mOperationLogic.getOperation(mAutoSyncOpenOperationId);
                if (operationDto != null && operationDto.contentId != null && operationDto.contentId != 0) {
                    openReportView(operationDto);
                }
            }
        }
        mAutoSyncOpenOperationId = null;
        mSyncTargetOperationId = null;
    }

    /**
     * 作業一覧画面上部に未読のプッシュメッセージ最大３つ表示
     */
    @Override
    protected void reloadOperationPushMessageListView() {
        List<PushMessageDto> pushMessageDtoList = mPushMessageLogic.getUnreadPushMessageList();
        if (pushMessageDtoList.size() == 0) {
            mOperationPushMessageListView.setVisibility(View.GONE);
            return;
        }
        mOperationPushMessageListView.setVisibility(View.VISIBLE);
        mUnreadPushMessageListAdapter = new UnreadPushMessageListAdapter(OperationListActivity.this, pushMessageDtoList);
        mOperationPushMessageListView.setAdapter(mUnreadPushMessageListAdapter);

        mUnreadPushMessageListAdapter.setAdapterListener(new UnreadPushMessageListAdapter.UnreadPushMessageListAdapterListener() {
            @Override
            public void onMoveOperation(Long operationId) {
                Logger.d(TAG, "onMoveOperation operationId = " + operationId);
                if (needAutoSync()) {
                    autoSyncOperationId(operationId);
                } else {
                    OperationDto operationDto = mOperationLogic.getOperation(operationId);
                    ContentDto contentDto = contentDao.getContent(operationDto.contentId);
                    if (contentDto == null || !contentDto.downloadedFlg || contentDto.updatedFlg) {
                        showErrorDialog(R.string.msg_push_message_content_not_downloaded);
                    } else {
                        if (operationDto != null && operationDto.contentId != null && operationDto.contentId != 0) {
                            openReportView(operationDto);
                        }
                    }
                }
            }
        });

        mOperationPushMessageListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                showPushMessageListDialog();
            }
        });
    }
}
