package com.hongzhengtech.hzpaperlesssystem.ui.activities.document;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.hongzhengtech.hzpaperlesssystem.R;
import com.hongzhengtech.hzpaperlesssystem.bean.DocumentAnnotation;
import com.hongzhengtech.hzpaperlesssystem.bean.interaction.ReceivedData;
import com.hongzhengtech.hzpaperlesssystem.bean.interaction.ReceivedDataItem;
import com.hongzhengtech.hzpaperlesssystem.broadcast.SiteDataSavedReceiver;
import com.hongzhengtech.hzpaperlesssystem.db.real.PDFAnnotationService;
import com.hongzhengtech.hzpaperlesssystem.db.serviceInterfaces.ActionDescription;
import com.hongzhengtech.hzpaperlesssystem.db.serviceInterfaces.IPDFAnnotationService;
import com.hongzhengtech.hzpaperlesssystem.ui.activities.document.paint.InkPoint;
import com.hongzhengtech.hzpaperlesssystem.ui.activities.document.paint.MarkupValue;
import com.hongzhengtech.hzpaperlesssystem.ui.activities.document.paint.PaintPoints;
import com.hongzhengtech.hzpaperlesssystem.ui.activities.document.paint.Point;
import com.hongzhengtech.hzpaperlesssystem.ui.activities.document.paint.TeamPoint;
import com.hongzhengtech.hzpaperlesssystem.ui.activities.document.stack.MyOpAdd;
import com.hongzhengtech.hzpaperlesssystem.ui.dialogs.document.NoteDialog;
import com.hongzhengtech.hzpaperlesssystem.utils.PointsUtils;
import com.radaee.pdf.Document;
import com.radaee.pdf.Global;
import com.radaee.pdf.Page;
import com.radaee.reader.OPItem;
import com.radaee.reader.PDFLayoutOPStack;
import com.radaee.reader.PDFLayoutView;
import com.radaee.reader.SearchDialog;
import com.radaee.reader.SearchListener;
import com.radaee.reader.SendPostilDataListener;
import com.radaee.util.RadaeePluginCallback;
import com.radaee.view.PDFLayout;
import com.radaee.view.VPage;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * pdf 文档显示
 * Created by HZ on 2017/7/6.
 */

public class DocumentViewActivity extends Activity implements PDFLayoutView.PDFLayoutListener,SearchListener,SendPostilDataListener,com.hongzhengtech.hzpaperlesssystem.broadcast.ISiteDataSavedListener{

    private static final String TAG = "DocumentViewActivity";
    public static String DOCUMENT_ID;

    private LinearLayout m_layout = null;
    private Document m_doc = null;
    private PDFLayoutView m_view = null;
    private DocumentViewController  m_controller = null;
    private String mFindQuery = "";
    private boolean mDidShowReader = false;
    private Handler m_search_page_hander;
    private IPDFAnnotationService service;
    private NoteDialog noteDialog;

    /**
     * 供其他页面跳转过来使用
     * @param context
     * @param path 文档路径
     * @param pwd 解密密码
     * @param name 显示名称
     * @param docId 文档id
     */
    public static void startAction(Context context, String path, String pwd, String name, String docId) {
        Intent intent = new Intent(context, DocumentViewActivity.class);
        intent.putExtra("PDFPath", path);
        intent.putExtra("PDFPwd", pwd);
        intent.putExtra("PDFName", name);
        intent.putExtra("DocumentId", docId);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        m_search_page_hander = new Handler(){
            @Override
            public void handleMessage(Message msg){
                Integer curPage = new Integer(msg.arg1);
                Integer totalPage = new Integer(msg.arg2);
                Log.i("11111",curPage + "/" +totalPage);

                SearchDialog searchDialog = m_controller.getSearch_dialog();
                if(searchDialog != null)
                    searchDialog.setSeekData(curPage,totalPage);
            }
        };

        Global.Init( this );
        m_layout = (LinearLayout) LayoutInflater.from(this).inflate(R.layout.document_main, null);
        m_view = (PDFLayoutView)m_layout.findViewById(R.id.pdf_view);

        Intent intent = getIntent();
        String pdf_path = intent.getStringExtra("PDFPath");
        String pdf_pswd = intent.getStringExtra("PDFPwd");
        String pdf_name = intent.getStringExtra("PDFName");

        if(pdf_name != null && pdf_name != "") {
            if(pdf_name.length() > 16)
                pdf_name = pdf_name.substring(0,16) + "...";
            ((TextView) m_layout.findViewById(R.id.document_name)).setText(pdf_name);
        }
        if(pdf_path != null && pdf_path != "") {
            m_doc = new Document();
            int ret = m_doc.Open(pdf_path, pdf_pswd);
            ProcessOpenResult(ret);
        }
        DOCUMENT_ID = intent.getStringExtra("DocumentId");

        service = PDFAnnotationService.getInstance();
        setContentView(m_layout);

    }

    @Override
    protected void onStart() {
        super.onStart();
        SiteDataSavedReceiver.addListener(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        SiteDataSavedReceiver.removeListener(this);
    }

    private final void ProcessOpenResult(int ret){
        switch( ret ){
            case -1://need input password
                onFail(getString(com.radaee.viewlib.R.string.failed_invalid_password));
                break;
            case -2://unknown encryption
                onFail(getString(com.radaee.viewlib.R.string.failed_encryption));
                break;
            case -3://damaged or invalid format
                onFail(getString(com.radaee.viewlib.R.string.failed_invalid_format));
                break;
            case -10://access denied or invalid file path
                onFail(getString(com.radaee.viewlib.R.string.failed_invalid_path));
                break;
            case 0://succeeded, and continue
                OpenTask task = new OpenTask(false);
                task.execute();
                break;
            default://unknown error
                onFail(getString(com.radaee.viewlib.R.string.failed_unknown));
                break;
        }
    }

    private void onFail(String msg)//treat open failed.
    {
        m_doc.Close();
        m_doc = null;
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
        finish();
    }

    // TODO: 2017/7/27  刷新 刷新
    @Override
    public void onSiteDataSavedEvent(ReceivedData dataList) {
        Log.i(TAG, "onSiteDataSavedEvent:DocumentViewActivity ");
        List<ReceivedDataItem> dataItems=dataList.getList();
        for (int i = 0; i < dataItems.size(); i++) {
            if (dataItems.get(i).getTable().equals("Document")){
                ContentValues contentValues= dataItems.get(i).getContentValues();
                String doc_id= (String) contentValues.get(com.hongzhengtech.hzpaperlesssystem.bean.Document.DataColumns.ID);
                if (doc_id.equals(DOCUMENT_ID)){
                    int isPublish= (int) contentValues.get(com.hongzhengtech.hzpaperlesssystem.bean.Document.DataColumns.IsPublish);
                    Log.i(TAG, "onSiteDataSavedEvent: "+isPublish);
                    if (isPublish==0){
                        showMyDialog();
                    }
                }
            }
        }

    }

    private  void showMyDialog() {
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setTitle("当前文件已被取消！")
                .setIcon(R.mipmap.warning)
                .setNeutralButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        setResult(RESULT_OK);
                        finish();
                    }
                }).setCancelable(false).create();
        builder.show();

    }

    class OpenTask extends AsyncTask<Void, Integer, Integer>
    {
        private boolean need_save;
        private ProgressDialog dlg;
        private Handler handler;
        private Runnable runable;
        OpenTask(boolean need_save)
        {
            this.need_save = need_save;
        }
        @Override
        protected Integer doInBackground(Void... voids)
        {
            m_doc.GetPagesMaxSize();//it may spend much time for first invoking this method.
            return null;
        }
        @Override
        protected void onPreExecute()
        {
            handler = new Handler();
            runable = new Runnable()
            {
                public void run()
                {
                    dlg = ProgressDialog.show(DocumentViewActivity.this, getString(com.radaee.viewlib.R.string.please_wait), getString(com.radaee.viewlib.R.string.loading_pdf), true);
                }
            };
            handler.postDelayed(runable, 1000);//delay 1 second to display progress dialog.
        }

        @Override
        protected void onPostExecute(Integer integer)
        {
            m_view.PDFOpen(m_doc, DocumentViewActivity.this,DocumentViewActivity.this);
            m_view.setReadOnly(getIntent().getBooleanExtra("READ_ONLY", false));
            m_view.setSendListener(DocumentViewActivity.this);
            m_controller = new DocumentViewController(m_layout,m_view,DocumentViewActivity.this);
            if(dlg != null)
                dlg.dismiss();
            else
                handler.removeCallbacks(runable);

            int gotoPage = getIntent().getIntExtra("GOTO_PAGE", -1);
            if(gotoPage > 0)
                m_view.PDFGotoPage(gotoPage);
        }
    }

    @Override
    public void onPDFPageRendered(int pageno) {
        if(!mDidShowReader) {
            RadaeePluginCallback.getInstance().didShowReader();
            mDidShowReader = true;
        }
    }

    @Override
    public void onPDFCacheRendered(int pageno) {
        findViewById(R.id.progress).setVisibility(View.GONE);
    }

    @Override
    public void onPDFSearchFinished(boolean found) {
        if(!mFindQuery.equals(m_controller.getFindQuery())) {
            mFindQuery = m_controller.getFindQuery();
            RadaeePluginCallback.getInstance().didSearchTerm(mFindQuery, found);
        }
        if(m_controller.getSearch_dialog() != null) {
            m_controller.getSearch_dialog().dismiss();
        }
    }

    @Override
    public void OnPDFPageModified(int pageno) {
        //TODO
    }

    @Override
    public void OnPDFPageChanged(int pageno) {
        if(m_controller != null)
            m_controller.OnPageChanged(pageno);
        RadaeePluginCallback.getInstance().didChangePage(pageno);
    }

    @Override
    public void OnPDFAnnotTapped(VPage vpage, Page.Annotation annot) {
        if(m_controller != null){
            m_controller.OnAnnotTapped(annot);
        }
    }

    @Override
    public void OnPDFBlankTapped() {
        if(m_controller != null)
            m_controller.OnBlankTapped();
    }

    @Override
    public void OnPDFSelectEnd(String text) {
        //TODO
        final String sel_text = text;
        switch (m_controller.getCommTypeFlag()){
            case 1:
                m_view.PDFSetSelMarkup(1);
                break;
            case 2 :
                m_view.PDFSetSelMarkup(0);
                break;
            case 3:
                m_view.PDFSetSelMarkup(4);
                break;
            case 4:
                m_view.PDFSetSelMarkup(2);
                break;
        }
        //m_view.PDFSetSelect();//一次性
    }

    @Override
    public void selectEndSend(Page page,String text, Page.Annotation annotation, int[] paras) {
        String name = UUID.randomUUID().toString();
        annotation.SetName(name);
        float[] markup = annotation.GetMarkupRects();
        //Toast.makeText(DocumentViewActivity.this,markup.length + "",Toast.LENGTH_SHORT).show();
        TeamPoint[] rects = new TeamPoint[markup.length / 4];
        int index = 0;
        for(int i = 0; i < markup.length;) {
            if(i + 3 >= markup.length) {
                break;
            }
            InkPoint startPoint = new InkPoint(markup[i],markup[i+1]);
            InkPoint endPoint = new InkPoint(markup[i+2],markup[i+3]);
            i += 4;
            rects[index++] = new TeamPoint(startPoint,endPoint);
        }
        MarkupValue value = new MarkupValue(rects,paras[1],paras[2]);
        serviceAdd(name,text,paras[0],annotation.GetType(),value,page,annotation.GetIndexInPage());
        if(page != null)
            page.Close();
    }

    @Override
    public void inkEndSend(Page page,int flag,Page.Annotation annotation, int pageNo) {
        PaintPoints paintPoints = PaintPoints.getInstance();
        ArrayList<Point> points = paintPoints.exportInk(annotation);
        if(points == null)
            return;
        for(int i=0;i < points.size(); i++) {
            if(points.get(i).getType() == 2) {
                points.remove(i);
            }
        }
        InkPoint[] inkPoints = new InkPoint[points.size()];
        for(int i=0;i < points.size() ;i++) {
            Point p = points.get(i);
            inkPoints[i] = new InkPoint(p.getType(),p.getX(),p.getY());
        }
        MarkupValue value = new MarkupValue(inkPoints);
        if(flag == 0) {
            String name = UUID.randomUUID().toString();
            annotation.SetName(name);
            serviceAdd(name,null,pageNo,annotation.GetType(),value,page,annotation.GetIndexInPage());
        }else if(flag == 1) {
            DocumentAnnotation documentAnnotation = PDFAnnotationService.getInstance().getByName(annotation.GetName());
            if(documentAnnotation == null) {
                Toast.makeText(this,"更新失败",Toast.LENGTH_SHORT).show();
                return;
            }
            documentAnnotation.setValue(PointsUtils.getMarkValueJson(value));
            documentAnnotation.setPageno(pageNo);
            PDFAnnotationService.getInstance().update(documentAnnotation,ActionDescription.PDF_UPDATE_HANDWRITING_POSTIL);
        }
        if(page != null)
            page.Close();
    }

    @Override
    public void noteEndSend(Page page,int flag,String name,Page.Annotation annotation, int pageNo, float[] place) {
        if(flag == 0) {//add 数据
            noteDialog = new NoteDialog(this,name,annotation,pageNo,place);
            noteDialog.setPage(page);
            noteDialog.setM_view(m_view);
            noteDialog.setView(new EditText(this));
            noteDialog.show();
        } else {//update 数据
            DocumentAnnotation documentAnnotation = service.getByName(name);
            if(documentAnnotation == null) {
                Toast.makeText(this,"更新失败",Toast.LENGTH_SHORT).show();
                return;
            }
            noteDialog = new NoteDialog(this,name,annotation,documentAnnotation.getSubject(),documentAnnotation.getContent());
            noteDialog.setPage(page);
            noteDialog.setM_view(m_view);
            noteDialog.setView(new EditText(this));
            noteDialog.show();
            m_view.PDFEndAnnot();
        }
        //if(page != null)
            //page.Close();
    }

    private void serviceAdd(String name,String text,int pageNo,int type,MarkupValue value,Page page,int idx) {
        DocumentAnnotation annotation = new DocumentAnnotation();
        annotation.setName(name);
        annotation.setDocumentID(DocumentViewActivity.DOCUMENT_ID);
        annotation.setValue(PointsUtils.getMarkValueJson(value));//序列化
        annotation.setSubject(text);
        annotation.setPageno(pageNo);
        annotation.setAnnotType(type);
        service.add(annotation, getServiceOPLog(type));
        //addMyStack(annotation,page,idx);
    }

    private void addMyStack(DocumentAnnotation annotation,Page page,int idx) {
        PDFLayoutOPStack stack = m_view.getM_opstack();
        OPItem item = new MyOpAdd(annotation.getPageno(),page,idx);
        item.name = annotation.getName();
        item.value = annotation.getValue();
        item.subject = annotation.getSubject();
        item.content = annotation.getContent();
        item.annotType = annotation.getAnnotType();
        stack.push(item);
    }

    private String getServiceOPLog(int type) {
        switch (type) {
            case DocumentAnnotation.AnnotType.Highlight :
                return ActionDescription.PDF_SET_TEXT_HIGHLIGHT;
            case DocumentAnnotation.AnnotType.Squiggly :
                return ActionDescription.PDF_SET_TEXT_TILDE;
            case DocumentAnnotation.AnnotType.StrikeOut :
                return ActionDescription.PDF_SET_TEXT_STRIKETHROUGH;
            case DocumentAnnotation.AnnotType.Underline :
                return ActionDescription.PDF_SET_TEXT_UNDERLINE;
            case DocumentAnnotation.AnnotType.Ink :
                return ActionDescription.PDF_ADD_HANDWRITING_POSTIL;
        }
        return null;
    }

    @Override
    public void OnPDFOpenURI(String uri) {
        //TODO
    }

    @Override
    public void OnPDFOpenJS(String js) {
        Toast.makeText(DocumentViewActivity.this, R.string.todo_java_script, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void OnPDFOpenMovie(String path) {
        Toast.makeText(DocumentViewActivity.this, R.string.todo_play_movie, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void OnPDFOpenSound(int[] paras, String path) {
        Toast.makeText(DocumentViewActivity.this, R.string.todo_play_sound, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void OnPDFOpenAttachment(String path) {
        Toast.makeText(DocumentViewActivity.this, R.string.todo_attachment, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void OnPDFOpen3D(String path) {
        Toast.makeText(DocumentViewActivity.this, R.string.todo_3d, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void OnPDFZoomStart() {
    }

    @Override
    public void OnPDFZoomEnd() {
    }

    @Override
    public boolean OnPDFDoubleTapped(PDFLayout layout, float x, float y) {
        float mCurZoomLevel = layout.vGetZoom();
        if(m_view.PDFGetScale() <= m_view.PDFGetMinScale())
            Global.zoomStep = 1;
        if((mCurZoomLevel > Global.zoomLevel && Global.zoomStep > 0) ||
                (mCurZoomLevel == 1 && Global.zoomStep < 0)) //reverse zoom step
            Global.zoomStep *= -1;

        layout.vZoomSet((int) x, (int) y, layout.vGetPos((int) x, (int) y), mCurZoomLevel + Global.zoomStep);
        return true;
    }

    @Override
    public void OnSearchCurrentPage(int curPage, int totalPage) {
        Message msg = new Message();
        msg.arg1 = curPage;
        msg.arg2 = totalPage;
        this.m_search_page_hander.sendMessage(msg);
    }

}
