/*
 * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package jp.co.omronsoft.openwnn;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnTouchListener;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Button;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;


/**
 * The abstract class for user dictionary tool.
 *
 * @author Copyright (C) 2009, OMRON SOFTWARE CO., LTD.  All Rights Reserved.
 */
public abstract class UserDictionaryToolsList extends Activity
    implements View.OnClickListener, OnTouchListener, OnFocusChangeListener {

    /** The class name of the user dictionary tool */
    protected String  mListViewName;
    /** The class name of the user dictionary editor */
    protected String  mEditViewName;
    /** The package name of the user dictionary editor */
    protected String  mPackageName;

    /** ID of the menu item (add) */
    private final int MENU_ITEM_ADD = 0;
    /** ID of the menu item (edit) */
    private final int MENU_ITEM_EDIT = 1;
    /** ID of the menu item (delete) */
    private final int MENU_ITEM_DELETE = 2;
    /** ID of the menu item (initialize) */
    private final int MENU_ITEM_INIT = 3;
    
    /** ID of the dialog control (confirm deletion) */
    private final int DIALOG_CONTROL_DELETE_CONFIRM = 0;
    /** ID of the dialog control (confirm initialize) */
    private final int DIALOG_CONTROL_INIT_CONFIRM = 1;

    /** The size of font*/
    private final int WORD_TEXT_SIZE = 16;

    /** The color of background (unfocused item) */
    private final int UNFOCUS_BACKGROUND_COLOR = 0xFF242424;
    /** The color of background (focused item) */
    private final int FOCUS_BACKGROUND_COLOR = 0xFFFF8500;

    /** The minimum count of registered words */
    private final int MIN_WORD_COUNT = 0;
    /** The maximum count of registered words */
    private final int MAX_WORD_COUNT = 100;
    /** Maximum word count to display */
    private final int MAX_LIST_WORD_COUNT = 100;

    /** The threshold time of the double tapping */
    private final int DOUBLE_TAP_TIME = 300;

    /** Widgets which constitute this screen of activity */
    private Menu mMenu;
    /** Table layout for the lists */
    private TableLayout mTableLayout;
    /** Focusing view */
    private static View sFocusingView = null;
    /** Focusing pair view */
    private static View sFocusingPairView = null;

    /** Objects which control state transitions */
    private Intent mIntent;

    /** The number of the registered words */
    private int mWordCount = 0;

    /** The state of "Add" menu item */
    private boolean mAddMenuEnabled;
    /** The state of "Edit" menu item */
    private boolean mEditMenuEnabled;
    /** The state of "Delete" menu item */
    private boolean mDeleteMenuEnabled;
    /** The state of "Initialize" menu item */
    private boolean mInitMenuEnabled;

    /** {@code true} if the menu option is initialized */
    private boolean mInitializedMenu = false;
    /** {@code true} if one of word is selected */
    private boolean mSelectedWords;
    /** The viewID which is selected */
    private int mSelectedViewID = -1;
    /** The viewID which was selected previously */
    private static int sBeforeSelectedViewID = -1;
    /** The time of previous action */
    private static long sJustBeforeActionTime = -1;

    /** List of the words in the user dictionary */
    private ArrayList<WnnWord> mWordList = null;

    /** Work area for sorting the word list */
    private WnnWord[] mSortData;

    /** Whether the view is initialized */
    private boolean mInit = false;

    /** Page left button */
    private Button mLeftButton = null;

    /** Page right button */
    private Button mRightButton = null;

    /**
     * Send the specified event to IME
     *
     * @param ev    The event object
     * @return      {@code true} if this event is processed
     */
    protected abstract boolean sendEventToIME(OpenWnnEvent ev);
    /** Get the comparator for sorting the list */
    protected abstract Comparator<WnnWord> getComparator();

    /**
     * Create the header
     */
    protected abstract void  headerCreate();

    /** @see android.app.Activity#onCreate */
    @Override protected void onCreate(Bundle savedInstanceState) {


        super.onCreate(savedInstanceState);

        /* create XML layout */
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.user_dictionary_tools_list);
        mTableLayout = (TableLayout)findViewById(R.id.user_dictionary_tools_table);

        Button b = (Button)findViewById(R.id.user_dictionary_left_button);
        b.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    int pos = mWordCount - MAX_LIST_WORD_COUNT;
                    if (0 <= pos) {
                        mWordCount = pos;
                        updateWordList();
                        mTableLayout.findViewById(1).requestFocus();
                    }
                }
            });
        mLeftButton = b;

        b = (Button)findViewById(R.id.user_dictionary_right_button);
        b.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    int pos = mWordCount + MAX_LIST_WORD_COUNT;
                    if (pos < mWordList.size()) {
                        mWordCount = pos;
                        updateWordList();
                        mTableLayout.findViewById(1).requestFocus();
                    }
                }
            });
        mRightButton = b;

    }

    /** @see android.app.Activity#onStart */
    @Override protected void onStart() {
        super.onStart();
        sBeforeSelectedViewID = -1;
        sJustBeforeActionTime = -1;
        mWordList = getWords();

        headerCreate();
        final TextView leftText = (TextView) findViewById(R.id.user_dictionary_tools_list_title_words_count);
        leftText.setText(mWordList.size() + "/" + MAX_WORD_COUNT);

        updateWordList();
    }

    /**
     * Set parameters of table
     *
     * @param  w        The width of the table
     * @param  h        The height of the table
     * @return          The information of the layout
     */
    private TableLayout.LayoutParams tableCreateParam(int w, int h) {
        return new TableLayout.LayoutParams(w, h);
    }

    /** @see android.app.Activity#onCreateOptionsMenu */
    @Override public boolean onCreateOptionsMenu(Menu menu) {


        /* initialize the menu */
        menu.clear();
        /* set the menu item enable/disable */
        setOptionsMenuEnabled();
        /* [menu] add a word */
        menu.add(0, MENU_ITEM_ADD, 0, R.string.user_dictionary_add)
            .setIcon(android.R.drawable.ic_menu_add)
            .setEnabled(mAddMenuEnabled);
        /* [menu] edit a word */
        menu.add(0, MENU_ITEM_EDIT, 0, R.string.user_dictionary_edit)
            .setIcon(android.R.drawable.ic_menu_edit)
            .setEnabled(mEditMenuEnabled);
        /* [menu] delete a word */
        menu.add(0, MENU_ITEM_DELETE, 0, R.string.user_dictionary_delete)
            .setIcon(android.R.drawable.ic_menu_delete)
            .setEnabled(mDeleteMenuEnabled);
        /* [menu] clear the dictionary */
        menu.add(1, MENU_ITEM_INIT, 0, R.string.user_dictionary_init)
            .setIcon(android.R.drawable.ic_menu_delete)
            .setEnabled(mInitMenuEnabled);

        mMenu = menu;
        mInitializedMenu = true;


        return super.onCreateOptionsMenu(menu);
    }

    /**
     * Change state of the option menus according to a current state of the list widget
     */
    private void setOptionsMenuEnabled() {


        /* [menu] add a word */
        if (mWordList.size() >= MAX_WORD_COUNT) {
            /* disable if the number of registered word exceeds MAX_WORD_COUNT */
            mAddMenuEnabled = false;
        } else {
            mAddMenuEnabled = true;
        }
        
        /* [menu] edit a word/delete a word */
        if (mWordList.size() <= MIN_WORD_COUNT) {
            /* disable if no word is registered or no word is selected */
            mEditMenuEnabled = false;
            mDeleteMenuEnabled = false;
        } else {
            mEditMenuEnabled = true;
            if (mSelectedWords) {
                mDeleteMenuEnabled = true;
            } else {
                mDeleteMenuEnabled = false;
            }
        }
        
        /* [menu] clear the dictionary (always enabled) */
        mInitMenuEnabled = true;

    }

    /** @see android.app.Activity#onOptionsItemSelected */
    @Override public boolean onOptionsItemSelected(MenuItem item) {

        boolean ret;
        switch (item.getItemId()) {
        case MENU_ITEM_ADD:
            /* add a word */
            wordAdd();
            ret = true;
            break;

        case MENU_ITEM_EDIT:
            /* edit the word (show dialog) */
            wordEdit(sFocusingView, sFocusingPairView);
            ret = true;
            break;

        case MENU_ITEM_DELETE:
            /* delete the word (show dialog) */
            showDialog(DIALOG_CONTROL_DELETE_CONFIRM);
            ret = true;
            break;

        case MENU_ITEM_INIT:
            /* clear the dictionary (show dialog) */
            showDialog(DIALOG_CONTROL_INIT_CONFIRM);
            ret = true;
            break;

        default:
            ret = false;
        }

        return ret;
    }

    /** @see android.app.Activity#onKeyUp */
    @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
        /* open the menu if KEYCODE_DPAD_CENTER is pressed */
        if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
            openOptionsMenu();
            return true;
        }
         return super.onKeyUp(keyCode, event);
    }

    /** @see android.app.Activity#onCreateDialog */
    @Override protected Dialog onCreateDialog(int id) {
        switch (id) {
        case DIALOG_CONTROL_DELETE_CONFIRM:
            return new AlertDialog.Builder(UserDictionaryToolsList.this)
                .setMessage(R.string.user_dictionary_delete_confirm)
                .setNegativeButton(android.R.string.cancel, null)
                .setPositiveButton(android.R.string.ok, mDialogDeleteWords)
                .setCancelable(true)
                .create();

        case DIALOG_CONTROL_INIT_CONFIRM:
            return new AlertDialog.Builder(UserDictionaryToolsList.this)
                .setMessage(R.string.dialog_clear_user_dictionary_message)
                .setNegativeButton(android.R.string.cancel, null)
                .setPositiveButton(android.R.string.ok, mDialogInitWords)
                .setCancelable(true)
                .create();

        default:
            Log.e("OpenWnn", "onCreateDialog : Invaled Get DialogID. ID=" + id);
            break;
        }


        return super.onCreateDialog(id);
    }

    /**
     * Process the event when the button on the "Delete word" dialog is pushed
     *
     * @param  dialog    The information of the dialog
     * @param  button    The button that is pushed
     */
    private DialogInterface.OnClickListener mDialogDeleteWords =
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int button) {

                CharSequence focusString = ((TextView)sFocusingView).getText();
                CharSequence focusPairString = ((TextView)sFocusingPairView).getText();
                WnnWord wnnWordSearch = new WnnWord();

                if (mSelectedViewID > MAX_WORD_COUNT) {
                    wnnWordSearch.stroke = focusPairString.toString();
                    wnnWordSearch.candidate = focusString.toString();
                } else {
                    wnnWordSearch.stroke = focusString.toString();
                    wnnWordSearch.candidate = focusPairString.toString();
                }
                boolean deleted = deleteWord(wnnWordSearch);
                if (deleted) {
                    Toast.makeText(getApplicationContext(),
                                   R.string.user_dictionary_delete_complete,
                                   Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getApplicationContext(),
                                   R.string.user_dictionary_delete_fail,
                                   Toast.LENGTH_LONG).show();
                    return;
                }

                mWordList = getWords();
                int size = mWordList.size();
                if (size <= mWordCount) {
                    int newPos = (mWordCount - MAX_LIST_WORD_COUNT);
                    mWordCount = (0 <= newPos) ? newPos : 0;
                }
                updateWordList();

                TextView leftText = (TextView) findViewById(R.id.user_dictionary_tools_list_title_words_count);
                leftText.setText(size + "/" + MAX_WORD_COUNT);

                if (mInitializedMenu) {
                    onCreateOptionsMenu(mMenu);
                }
            }
        };
    
    /**
     * Process the event when the button on the "Initialize" dialog is pushed
     *
     * @param  dialog    The information of the dialog
     * @param  button    The button that is pushed
     */
    private DialogInterface.OnClickListener mDialogInitWords =
        new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int button) {

                /* clear the user dictionary */
                OpenWnnEvent ev = new OpenWnnEvent(OpenWnnEvent.INITIALIZE_USER_DICTIONARY, new WnnWord());

                sendEventToIME(ev);
                /* show the message */
                Toast.makeText(getApplicationContext(), R.string.dialog_clear_user_dictionary_done,
                               Toast.LENGTH_LONG).show();
                mWordList = new ArrayList<WnnWord>();
                mWordCount = 0;
                updateWordList();
                TextView leftText = (TextView) findViewById(R.id.user_dictionary_tools_list_title_words_count);
                leftText.setText(mWordList.size() + "/" + MAX_WORD_COUNT);

                if (mInitializedMenu) {
                    onCreateOptionsMenu(mMenu);
                }
            }
        };

    
    /** @see android.view.View.OnClickListener#onClick */
    public void onClick(View arg0) {
    }

    /** @see android.view.View.OnTouchListener#onTouch */
    public boolean onTouch(View v, MotionEvent e) {


        mSelectedViewID = ((TextView)v).getId();
        switch (e.getAction()) {
        case MotionEvent.ACTION_DOWN:
            /* double tap handling */
            if (sBeforeSelectedViewID != ((TextView)v).getId()) {
                /* save the view id if the id is not same as previously selected one */
                sBeforeSelectedViewID = ((TextView)v).getId();
            } else {
                if ((e.getDownTime() - sJustBeforeActionTime) < DOUBLE_TAP_TIME) {
                    /* edit the word if double tapped */
                    sFocusingView = v;
                    sFocusingPairView = ((UserDictionaryToolsListFocus)v).getPairView();
                    wordEdit(sFocusingView, sFocusingPairView);
                }
            }
            /* save the action time */
            sJustBeforeActionTime = e.getDownTime();
            break;
        }

        return false;
    }

    /** @see android.view.View.OnFocusChangeListener#onFocusChange */
    public void onFocusChange(View v, boolean hasFocus) {

        mSelectedViewID = ((TextView)v).getId();
        sFocusingView = v;
        sFocusingPairView = ((UserDictionaryToolsListFocus)v).getPairView();
        if (hasFocus) {
            ((TextView)v).setTextColor(Color.BLACK);
            v.setBackgroundColor(FOCUS_BACKGROUND_COLOR);
            ((TextView)sFocusingPairView).setTextColor(Color.BLACK);
            sFocusingPairView.setBackgroundColor(FOCUS_BACKGROUND_COLOR);
            mSelectedWords = true;
        } else {
            mSelectedWords = false;
            ((TextView)v).setTextColor(Color.LTGRAY);
            v.setBackgroundColor(UNFOCUS_BACKGROUND_COLOR);
            ((TextView)sFocusingPairView).setTextColor(Color.LTGRAY);
            sFocusingPairView.setBackgroundColor(UNFOCUS_BACKGROUND_COLOR);
        }
        if (mInitializedMenu) {
            onCreateOptionsMenu(mMenu);
        }
    }

    /**
     * Add the word
     */
    public void wordAdd() {
        /** change to the edit window */
        screenTransition(Intent.ACTION_INSERT, mEditViewName);
    }

    /**
     * Edit the specified word
     *
     * @param  focusView       The information of view
     * @param  focusPairView   The information of pair of view
     */
    public void wordEdit(View focusView, View focusPairView) {
        if (mSelectedViewID > MAX_WORD_COUNT) {
            createUserDictionaryToolsEdit(focusPairView, focusView);
        } else {
            createUserDictionaryToolsEdit(focusView, focusPairView);
        }
        screenTransition(Intent.ACTION_EDIT, mEditViewName);
    }

    /**
     * The internal process of editing the specified word
     *
     * @param  focusView        The information of view
     * @param  focusPairView    The information of pair of view
     */
    protected abstract UserDictionaryToolsEdit createUserDictionaryToolsEdit(View focusView, View focusPairView);

    /**
     * Delete the specified word
     *
     * @param  searchword   The information of searching
     * @return          {@code true} if success; {@code false} if fail.
     */
    public boolean deleteWord(WnnWord searchword) {
        OpenWnnEvent event = new OpenWnnEvent(OpenWnnEvent.LIST_WORDS_IN_USER_DICTIONARY,
                                              WnnEngine.DICTIONARY_TYPE_USER,
                                              searchword);

        boolean deleted = false;
        sendEventToIME(event);
        for( int i=0; i < MAX_WORD_COUNT; i++) {
            WnnWord getword = new WnnWord();
            event = new OpenWnnEvent(OpenWnnEvent.GET_WORD,
                                     getword);
            sendEventToIME(event);
            getword = event.word;
            int len = getword.candidate.length();
            if (len == 0) {
                break;
            }
            if (searchword.candidate.equals(getword.candidate)) {
                WnnWord delword = new WnnWord();
                delword.stroke = searchword.stroke;
                delword.candidate = searchword.candidate;
                delword.id = i;
                event = new OpenWnnEvent(OpenWnnEvent.DELETE_WORD,
                                         delword);
                deleted = sendEventToIME(event);
                break;
            }
        }
        
        if (mInitializedMenu) {
            onCreateOptionsMenu(mMenu);
        }

        return deleted;
    }


    /**
     * Processing the transition of screen
     *
     * @param  action       The string of action
     * @param  classname    The class name
     */
    private void screenTransition(String action, String classname) {

        if (action.equals("")) {
            mIntent = new Intent();
        } else {
            mIntent = new Intent(action);
        }
        mIntent.setClassName(mPackageName, classname);
        startActivity(mIntent);
        finish();
    }

    /**
     * Get the list of words in the user dictionary.
     * @return The list of words
     */
    private ArrayList<WnnWord> getWords() {
        WnnWord word = new WnnWord();
        OpenWnnEvent event = new OpenWnnEvent(OpenWnnEvent.LIST_WORDS_IN_USER_DICTIONARY,
                                              WnnEngine.DICTIONARY_TYPE_USER,
                                              word);
        sendEventToIME(event);

        ArrayList<WnnWord> list = new ArrayList<WnnWord>();
        for (int i = 0; i < MAX_WORD_COUNT; i++) {
            event = new OpenWnnEvent(OpenWnnEvent.GET_WORD, word);
            if (!sendEventToIME(event)) {
                break;
            }
            list.add(event.word);
        }

        compareTo(list);

        return list;
    }

    /**
     * Sort the list of words
     * @param array The array list of the words
     */
    protected void compareTo(ArrayList<WnnWord> array) {
        mSortData = new WnnWord[array.size()];
        array.toArray(mSortData);
        Arrays.sort(mSortData, getComparator());   
    }


    /**
     * Update the word list.
     */
    private void updateWordList() {
        if (!mInit) {
            mInit = true;
            mSelectedViewID = 1;

            Window window = getWindow();
            WindowManager windowManager = window.getWindowManager();
            Display display = windowManager.getDefaultDisplay();
            int system_width = display.getWidth();

            for (int i = 1; i <= MAX_LIST_WORD_COUNT; i++) {
                TableRow row = new TableRow(this);
                UserDictionaryToolsListFocus stroke = new UserDictionaryToolsListFocus(this);
                stroke.setId(i);
                stroke.setWidth(system_width/2);
                stroke.setTextSize(WORD_TEXT_SIZE);
                stroke.setTextColor(Color.LTGRAY);
                stroke.setBackgroundColor(UNFOCUS_BACKGROUND_COLOR);
                stroke.setSingleLine();
                stroke.setPadding(1,0,1,1);
                stroke.setEllipsize(TextUtils.TruncateAt.END);
                stroke.setClickable(true);
                stroke.setFocusable(true);
                stroke.setFocusableInTouchMode(true);
                stroke.setOnTouchListener(this);
                stroke.setOnFocusChangeListener(this);

                UserDictionaryToolsListFocus candidate = new UserDictionaryToolsListFocus(this);
                candidate.setId(i+MAX_WORD_COUNT);
                candidate.setWidth(system_width/2);
                candidate.setTextSize(WORD_TEXT_SIZE);
                candidate.setTextColor(Color.LTGRAY);
                candidate.setBackgroundColor(UNFOCUS_BACKGROUND_COLOR);
                candidate.setSingleLine();
                candidate.setPadding(1,0,1,1);
                candidate.setEllipsize(TextUtils.TruncateAt.END);
                candidate.setClickable(true);
                candidate.setFocusable(true);
                candidate.setFocusableInTouchMode(true);
                candidate.setOnTouchListener(this);
                candidate.setOnFocusChangeListener(this);

                stroke.setPairView(candidate);
                candidate.setPairView(stroke);

                row.addView(stroke);
                row.addView(candidate);
                mTableLayout.addView(row, tableCreateParam(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            }
        }

        int size = mWordList.size();
        int start = mWordCount;

        TextView t = (TextView)findViewById(R.id.user_dictionary_position_indicator);
        if (size <= MAX_LIST_WORD_COUNT) {
            ((View)mLeftButton.getParent()).setVisibility(View.GONE);
        } else {
            ((View)mLeftButton.getParent()).setVisibility(View.VISIBLE);
            int last = (start + MAX_LIST_WORD_COUNT);
            t.setText((start + 1) + " - " + Math.min(last, size));

            mLeftButton.setEnabled(start != 0);
            mRightButton.setEnabled(last < size);
        }

        int selectedId = mSelectedViewID - ((MAX_WORD_COUNT < mSelectedViewID) ? MAX_WORD_COUNT : 0);
        
        for (int i = 0; i < MAX_LIST_WORD_COUNT; i++) {
            if ((size - 1) < (start + i)) {
                if ((0 < i) && (selectedId == (i + 1))) {
                    mTableLayout.findViewById(i).requestFocus();
                }

                ((View)(mTableLayout.findViewById(i + 1)).getParent()).setVisibility(View.GONE);
                continue;
            }

            WnnWord wnnWordGet;
            wnnWordGet = mSortData[start + i];
            int len_stroke = wnnWordGet.stroke.length();
            int len_candidate = wnnWordGet.candidate.length();
            if (len_stroke == 0 || len_candidate == 0) {
                break;
            }

            if (selectedId == i + 1) {
                mTableLayout.findViewById(i + 1).requestFocus();
            }

            TextView text = (TextView)mTableLayout.findViewById(i + 1);
            text.setText(wnnWordGet.stroke);
            text = (TextView)mTableLayout.findViewById(i + 1 + MAX_WORD_COUNT);
            text.setText(wnnWordGet.candidate);
            ((View)text.getParent()).setVisibility(View.VISIBLE);
        }
        mTableLayout.requestLayout();
    }
}
