/*
 * Copyright (C) 2008-2012  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 java.util.Iterator;
import java.util.ArrayList;

import android.util.Log;

/**
 * The container class of composing string.
 *
 * This interface is for the class includes information about the
 * input string, the converted string and its decoration.
 * {@link LetterConverter} and {@link WnnEngine} get the input string from it, and
 * store the converted string into it.
 *
 * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
 */
public class ComposingText {
    /**
     * Text layer 0.
     * <br>
     * This text layer holds key strokes.<br>
     * (ex) Romaji in Japanese.  Parts of Hangul in Korean.
     */
    public static final int LAYER0  = 0;
    /**
     * Text layer 1.
     * <br>
     * This text layer holds the result of the letter converter.<br>
     * (ex) Hiragana in Japanese. Pinyin in Chinese. Hangul in Korean.
     */
    public static final int LAYER1  = 1;
    /**
     * Text layer 2.
     * <br>
     * This text layer holds the result of the consecutive clause converter.<br>
     * (ex) the result of Kana-to-Kanji conversion in Japanese,
     *      Pinyin-to-Kanji conversion in Chinese, Hangul-to-Hanja conversion in Korean language.
     */
    public static final int LAYER2  = 2;
    /** Maximum number of layers */
    public static final int MAX_LAYER = 3;

    /** Composing text's layer data */
    protected ArrayList<StrSegment>[] mStringLayer;
    /** Cursor position */
    protected int[] mCursor;

    /**
     * Constructor
     */
    public ComposingText() {
        mStringLayer = new ArrayList[MAX_LAYER];
        mCursor = new int[MAX_LAYER];
        for (int i = 0; i < MAX_LAYER; i++) {
            mStringLayer[i] = new ArrayList<StrSegment>();
            mCursor[i] = 0;
        }
    }

    /**
     * Output internal information to the log.
     */
    public void debugout() {
        for (int i = 0; i < MAX_LAYER; i++) {
            Log.d("OpenWnn", "ComposingText["+i+"]");
            Log.d("OpenWnn", "  cur = " + mCursor[i]);
            String tmp = "";
            for (Iterator<StrSegment> it = mStringLayer[i].iterator(); it.hasNext();) {
                StrSegment ss = it.next();
                tmp += "(" + ss.string + "," + ss.from + "," + ss.to + ")";
            }
            Log.d("OpenWnn", "  str = "+tmp);
        }
    }

    /**
     * Get a {@link StrSegment} at the position specified.
     *
     * @param layer     Layer
     * @param pos       Position (<0 : the tail segment)
     *
     * @return          The segment; {@code null} if error occurs.
     */
    public StrSegment getStrSegment(int layer, int pos) {
        try {
            ArrayList<StrSegment> strLayer = mStringLayer[layer];
            if (pos < 0) {
                pos = strLayer.size() - 1;
            }
            if (pos >= strLayer.size() || pos < 0) {
                return null;
            }
            return strLayer.get(pos);
        } catch (Exception ex) {
            return null;
        }
    } 

    /**
     * Convert the range of segments to a string.
     *
     * @param layer     Layer
     * @param from      Convert range from
     * @param to        Convert range to
     * @return          The string converted; {@code null} if error occurs.
     */
    public String toString(int layer, int from, int to) {
        try {
            StringBuffer buf = new StringBuffer();
            ArrayList<StrSegment> strLayer = mStringLayer[layer];
            
            for (int i = from; i <= to; i++) {
                StrSegment ss = strLayer.get(i);
                buf.append(ss.string);
            }
            return buf.toString();
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * Convert segments of the layer to a string.
     *
     * @param layer     Layer
     * @return          The string converted; {@code null} if error occurs.
     */
    public String toString(int layer) {
        return this.toString(layer, 0, mStringLayer[layer].size() - 1);
    }

    /**
     * Update the upper layer's data.
     *
     * @param layer         The base layer
     * @param mod_from      Modified from
     * @param mod_len       Length after modified (# of StrSegments from {@code mod_from})
     * @param org_len       Length before modified (# of StrSegments from {@code mod_from})
     */
    private void modifyUpper(int layer, int mod_from, int mod_len, int org_len) {
        if (layer >= MAX_LAYER - 1) {
            /* no layer above */
            return;
        }

        int uplayer = layer + 1;
        ArrayList<StrSegment> strUplayer = mStringLayer[uplayer];
        if (strUplayer.size() <= 0) {
            /* 
             * if there is no element on above layer,
             * add a element includes whole elements of the lower layer.
             */
            strUplayer.add(new StrSegment(toString(layer), 0, mStringLayer[layer].size() - 1));
            modifyUpper(uplayer, 0, 1, 0);
            return;
        }

        int mod_to = mod_from + ((mod_len == 0)? 0 : (mod_len - 1));
        int org_to = mod_from + ((org_len == 0)? 0 : (org_len - 1));
        StrSegment last = strUplayer.get(strUplayer.size() - 1);
        if (last.to < mod_from) {
            /* add at the tail */
            last.to = mod_to;
            last.string = toString(layer, last.from, last.to);
            modifyUpper(uplayer, strUplayer.size()-1, 1, 1);
            return;
        }

        int uplayer_mod_from = -1;
        int uplayer_org_to = -1;
        for (int i = 0; i < strUplayer.size(); i++) {
            StrSegment ss = strUplayer.get(i);
            if (ss.from > mod_from) {
                if (ss.to <= org_to) {
                    /* the segment is included */
                    if (uplayer_mod_from < 0) {
                        uplayer_mod_from = i;
                    }
                    uplayer_org_to = i;
                } else {
                    /* included in this segment */
                    uplayer_org_to = i;
                    break;
                }
            } else {
                if (org_len == 0 && ss.from == mod_from) {
                    /* when an element is added */
                    uplayer_mod_from = i - 1;
                    uplayer_org_to   = i - 1;
                    break;
                } else {
                    /* start from this segment */
                    uplayer_mod_from = i;
                    uplayer_org_to = i;
                    if (ss.to >= org_to) {
                        break;
                    }
                }
            }
        }
        
        int diff = mod_len - org_len;
        if (uplayer_mod_from >= 0) {
            /* update an element */
            StrSegment ss = strUplayer.get(uplayer_mod_from);
            int last_to = ss.to;
            int next = uplayer_mod_from + 1;
            for (int i = next; i <= uplayer_org_to; i++) {
                ss = strUplayer.get(next);
                if (last_to > ss.to) {
                    last_to = ss.to;
                }
                strUplayer.remove(next);
            }
            ss.to = (last_to < mod_to)? mod_to : (last_to + diff);
            
            ss.string = toString(layer, ss.from, ss.to);
            
            for (int i = next; i < strUplayer.size(); i++) {
                ss = strUplayer.get(i);
                ss.from += diff;
                ss.to   += diff;
            }
            
            modifyUpper(uplayer, uplayer_mod_from, 1, uplayer_org_to - uplayer_mod_from + 1);
        } else {
            /* add an element at the head */
            StrSegment ss = new StrSegment(toString(layer, mod_from, mod_to),
                                           mod_from, mod_to); 
            strUplayer.add(0, ss);
            for (int i = 1; i < strUplayer.size(); i++) {
                ss = strUplayer.get(i);
                ss.from += diff;
                ss.to   += diff;
            }
            modifyUpper(uplayer, 0, 1, 0);
        }
        
        return;
    }

    /**
     * Insert a {@link StrSegment} at the cursor position.
     * 
     * @param layer Layer to insert
     * @param str   String
     **/
    public void insertStrSegment(int layer, StrSegment str) {
        int cursor = mCursor[layer];
        mStringLayer[layer].add(cursor, str);
        modifyUpper(layer, cursor, 1, 0);
        setCursor(layer, cursor + 1);
    }
    
    /**
     * Insert a {@link StrSegment} at the cursor position(without merging to the previous segment).
     * <p>
     * @param layer1        Layer to insert
     * @param layer2        Never merge to the previous segment from {@code layer1} to {@code layer2}.
     * @param str           String
     **/
    public void insertStrSegment(int layer1, int layer2, StrSegment str) {
        mStringLayer[layer1].add(mCursor[layer1], str);
        mCursor[layer1]++;
        
        for (int i = layer1 + 1; i <= layer2; i++) {
            int pos = mCursor[i-1] - 1;
            StrSegment tmp = new StrSegment(str.string, pos, pos);
            ArrayList<StrSegment> strLayer = mStringLayer[i];
            strLayer.add(mCursor[i], tmp);
            mCursor[i]++;
            for (int j = mCursor[i]; j < strLayer.size(); j++) {
                StrSegment ss = strLayer.get(j);
                ss.from++;
                ss.to++;
            }
        }
        int cursor = mCursor[layer2];
        modifyUpper(layer2, cursor - 1, 1, 0);
        setCursor(layer2, cursor);
    }
    
    /**
     * Replace segments at the range specified.
     *
     * @param layer     Layer
     * @param str       String segment array to replace
     * @param from      Replace from
     * @param to        Replace to
     **/
    protected void replaceStrSegment0(int layer, StrSegment[] str, int from, int to) {
        ArrayList<StrSegment> strLayer = mStringLayer[layer];

        if (from < 0 || from > strLayer.size()) {
            from = strLayer.size();
        }
        if (to < 0 || to > strLayer.size()) {
            to = strLayer.size();
        }
        for (int i = from; i <= to; i++) {
            strLayer.remove(from);
        }
        for (int i = str.length - 1; i >= 0; i--) {
            strLayer.add(from, str[i]);
        }
        
        modifyUpper(layer, from, str.length, to - from + 1);
    }
    
    /**
     * Replace segments at the range specified.
     *
     * @param layer     Layer
     * @param str       String segment array to replace
     * @param num       Size of string segment array
     **/
    public void replaceStrSegment(int layer, StrSegment[] str, int num) {
        int cursor = mCursor[layer];
        replaceStrSegment0(layer, str, cursor - num, cursor - 1);
        setCursor(layer, cursor + str.length - num);
    }
    
    /**
     * Replace the segment at the cursor.
     *
     * @param layer     Layer
     * @param str       String segment to replace
     **/
    public void replaceStrSegment(int layer, StrSegment[] str) {
        int cursor = mCursor[layer];
        replaceStrSegment0(layer, str, cursor - 1, cursor - 1);
        setCursor(layer, cursor + str.length - 1);
    }

    /**
     * Delete segments.
     * 
     * @param layer Layer
     * @param from  Delete from
     * @param to    Delete to
     **/
    public void deleteStrSegment(int layer, int from, int to) {
        int[] fromL = new int[] {-1, -1, -1};
        int[] toL   = new int[] {-1, -1, -1};

        ArrayList<StrSegment> strLayer2 = mStringLayer[2];
        ArrayList<StrSegment> strLayer1 = mStringLayer[1];
        
        if (layer == 2) {
            fromL[2] = from;
            toL[2]   = to;
            fromL[1] = strLayer2.get(from).from;
            toL[1]   = strLayer2.get(to).to;
            fromL[0] = strLayer1.get(fromL[1]).from;
            toL[0]   = strLayer1.get(toL[1]).to;
        } else if (layer == 1) {
            fromL[1] = from;
            toL[1]   = to;
            fromL[0] = strLayer1.get(from).from;
            toL[0]   = strLayer1.get(to).to;
        } else {
            fromL[0] = from;
            toL[0]   = to;
        }

        int diff = to - from + 1;
        for (int lv = 0; lv < MAX_LAYER; lv++) {
            if (fromL[lv] >= 0) {
                deleteStrSegment0(lv, fromL[lv], toL[lv], diff);
            } else {
                int boundary_from = -1;
                int boundary_to   = -1;
                ArrayList<StrSegment> strLayer = mStringLayer[lv];
                for (int i = 0; i < strLayer.size(); i++) {
                    StrSegment ss = (StrSegment)strLayer.get(i);
                    if ((ss.from >= fromL[lv-1] && ss.from <= toL[lv-1]) ||
                        (ss.to >= fromL[lv-1] && ss.to <= toL[lv-1]) ) {
                        if (fromL[lv] < 0) {
                            fromL[lv] = i;
                            boundary_from = ss.from;
                        }
                        toL[lv] = i;
                        boundary_to = ss.to;
                    } else if (ss.from <= fromL[lv-1] && ss.to >= toL[lv-1]) {
                        boundary_from = ss.from;
                        boundary_to   = ss.to;
                        fromL[lv] = i;
                        toL[lv] = i;
                        break;
                    } else if (ss.from > toL[lv-1]) {
                        break;
                    }
                }
                if (boundary_from != fromL[lv-1] || boundary_to != toL[lv-1]) {
                    deleteStrSegment0(lv, fromL[lv] + 1, toL[lv], diff);
                    boundary_to -= diff;
                    StrSegment[] tmp = new StrSegment[] {
                        (new StrSegment(toString(lv-1), boundary_from, boundary_to))
                    };
                    replaceStrSegment0(lv, tmp, fromL[lv], fromL[lv]);
                    return;
                } else {
                    deleteStrSegment0(lv, fromL[lv], toL[lv], diff);
                }
            }
            diff = toL[lv] - fromL[lv] + 1;
        }
    }

    /**
     * Delete segments (internal method).
     * 
     * @param layer     Layer
     * @param from      Delete from
     * @param to        Delete to
     * @param diff      Differential
     **/
    private void deleteStrSegment0(int layer, int from, int to, int diff) {
        ArrayList<StrSegment> strLayer = mStringLayer[layer];
        if (diff != 0) {
            for (int i = to + 1; i < strLayer.size(); i++) {
                StrSegment ss = strLayer.get(i);
                ss.from -= diff;
                ss.to   -= diff;
            }
        }
        for (int i = from; i <= to; i++) {
            strLayer.remove(from);
        }
    }

    /**
     * Delete a segment at the cursor.
     * 
     * @param layer         Layer
     * @param rightside     {@code true} if direction is rightward at the cursor, {@code false} if direction is leftward at the cursor
     * @return              The number of string segments in the specified layer
     **/
    public int delete(int layer, boolean rightside) {
        int cursor = mCursor[layer];
        ArrayList<StrSegment> strLayer = mStringLayer[layer];

        if (!rightside && cursor > 0) {
            deleteStrSegment(layer, cursor-1, cursor-1);
            setCursor(layer, cursor - 1);
        } else if (rightside && cursor < strLayer.size()) {
            deleteStrSegment(layer, cursor, cursor);
            setCursor(layer, cursor);
        }
        return strLayer.size();
    }

    /**
     * Get the string layer.
     *
     * @param layer     Layer
     * @return          {@link ArrayList} of {@link StrSegment}; {@code null} if error.
     **/
    public ArrayList<StrSegment> getStringLayer(int layer) {
        try {
            return mStringLayer[layer];
        } catch (Exception ex) {
            return null;
        }
    }

    /**
     * Get upper the segment which includes the position.
     * 
     * @param layer     Layer   
     * @param pos       Position        
     * @return      Index of upper segment
     */
    private int included(int layer, int pos) {
        if (pos == 0) {
            return 0;
        }
        int uplayer = layer + 1;
        int i;
        ArrayList<StrSegment> strLayer = mStringLayer[uplayer];
        for (i = 0; i < strLayer.size(); i++) {
            StrSegment ss = strLayer.get(i);
            if (ss.from <= pos && pos <= ss.to) {
                break;
            }
        }
        return i;
    }

    /**
     * Set the cursor.
     * 
     * @param layer     Layer
     * @param pos       Position of cursor
     * @return      New position of cursor
     */
    public int setCursor(int layer, int pos) {
        if (pos > mStringLayer[layer].size()) {
            pos = mStringLayer[layer].size();
        }
        if (pos < 0) {
            pos = 0;
        }
        if (layer == 0) {
            mCursor[0] = pos;
            mCursor[1] = included(0, pos);
            mCursor[2] = included(1, mCursor[1]);
        } else if (layer == 1) {
            mCursor[2] = included(1, pos);
            mCursor[1] = pos;
            mCursor[0] = (pos > 0)? mStringLayer[1].get(pos - 1).to+1 : 0;
        } else {
            mCursor[2] = pos;
            mCursor[1] = (pos > 0)? mStringLayer[2].get(pos - 1).to+1 : 0;
            mCursor[0] = (mCursor[1] > 0)? mStringLayer[1].get(mCursor[1] - 1).to+1 : 0;
        }
        return pos;
    }

    /**
     * Move the cursor.
     *
     * @param layer     Layer
     * @param diff      Relative position from current cursor position
     * @return      New position of cursor
     **/
    public int moveCursor(int layer, int diff) {
        int c = mCursor[layer] + diff;

        return setCursor(layer, c);
    }

    /**
     * Get the cursor position.
     *
     * @param layer     Layer
     * @return cursor   Current position of cursor
     **/
    public int getCursor(int layer) {
        return mCursor[layer];
    }

    /**
     * Get the number of segments.
     *
     * @param layer     Layer
     * @return          Number of segments
     **/
    public int size(int layer) {
        return mStringLayer[layer].size();
    }

    /**
     * Clear all information.
     */
    public void clear() {
        for (int i = 0; i < MAX_LAYER; i++) {
            mStringLayer[i].clear();
            mCursor[i] = 0;
        }
    }
}
