1053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project/*
2053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
3053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project *
4053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * you may not use this file except in compliance with the License.
6053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * You may obtain a copy of the License at
7053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project *
8053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project *
10053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * See the License for the specific language governing permissions and
14053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * limitations under the License.
15053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project */
16053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
17053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Projectpackage jp.co.omronsoft.openwnn;
18053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
19053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Projectimport java.util.Iterator;
20053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Projectimport java.util.ArrayList;
21053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
22053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Projectimport android.util.Log;
23053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
24053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project/**
25d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa * The container class of composing string.
26053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project *
27053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * This interface is for the class includes information about the
28053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * input string, the converted string and its decoration.
29d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa * {@link LetterConverter} and {@link WnnEngine} get the input string from it, and
30053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project * store the converted string into it.
31053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project *
32d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
33053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project */
34053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Projectpublic class ComposingText {
35053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
36053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Text layer 0.
37053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * <br>
38053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * This text layer holds key strokes.<br>
39053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * (ex) Romaji in Japanese.  Parts of Hangul in Korean.
40053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
41053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public static final int LAYER0  = 0;
42053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
43053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Text layer 1.
44053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * <br>
45053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * This text layer holds the result of the letter converter.<br>
46053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * (ex) Hiragana in Japanese. Pinyin in Chinese. Hangul in Korean.
47053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
48053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public static final int LAYER1  = 1;
49053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
50053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Text layer 2.
51053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * <br>
52053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * This text layer holds the result of the consecutive clause converter.<br>
53053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * (ex) the result of Kana-to-Kanji conversion in Japanese,
54053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *      Pinyin-to-Kanji conversion in Chinese, Hangul-to-Hanja conversion in Korean language.
55053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
56053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public static final int LAYER2  = 2;
57053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /** Maximum number of layers */
58053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public static final int MAX_LAYER = 3;
59053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
60053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /** Composing text's layer data */
61053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    protected ArrayList<StrSegment>[] mStringLayer;
62053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /** Cursor position */
63053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    protected int[] mCursor;
64053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
65053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
66053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Constructor
67053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
68053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public ComposingText() {
69053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        mStringLayer = new ArrayList[MAX_LAYER];
70053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        mCursor = new int[MAX_LAYER];
71053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int i = 0; i < MAX_LAYER; i++) {
72053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mStringLayer[i] = new ArrayList<StrSegment>();
73053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[i] = 0;
74053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
75053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
76053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
77053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
78053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Output internal information to the log.
79053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
80053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public void debugout() {
81053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int i = 0; i < MAX_LAYER; i++) {
82053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            Log.d("OpenWnn", "ComposingText["+i+"]");
83053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            Log.d("OpenWnn", "  cur = " + mCursor[i]);
84053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            String tmp = "";
85053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            for (Iterator<StrSegment> it = mStringLayer[i].iterator(); it.hasNext();) {
86053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                StrSegment ss = it.next();
87053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                tmp += "(" + ss.string + "," + ss.from + "," + ss.to + ")";
88053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
89053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            Log.d("OpenWnn", "  str = "+tmp);
90053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
91053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
92053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
93053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
94d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * Get a {@link StrSegment} at the position specified.
95053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
96d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
97d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param pos       Position (<0 : the tail segment)
98053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
99d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return          The segment; {@code null} if error occurs.
100053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
101053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public StrSegment getStrSegment(int layer, int pos) {
102053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        try {
103053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            ArrayList<StrSegment> strLayer = mStringLayer[layer];
104053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            if (pos < 0) {
105053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                pos = strLayer.size() - 1;
106053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
107053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            if (pos >= strLayer.size() || pos < 0) {
108053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                return null;
109053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
110053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return strLayer.get(pos);
111053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } catch (Exception ex) {
112053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return null;
113053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
114053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
115053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
116053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
117053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Convert the range of segments to a string.
118053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
119d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
120d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param from      Convert range from
121d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param to        Convert range to
122d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return          The string converted; {@code null} if error occurs.
123053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
124053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public String toString(int layer, int from, int to) {
125053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        try {
126053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            StringBuffer buf = new StringBuffer();
127053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            ArrayList<StrSegment> strLayer = mStringLayer[layer];
128053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
129053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            for (int i = from; i <= to; i++) {
130053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                StrSegment ss = strLayer.get(i);
131053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                buf.append(ss.string);
132053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
133053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return buf.toString();
134053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } catch (Exception ex) {
135053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return null;
136053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
137053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
138053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
139053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
140053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Convert segments of the layer to a string.
141053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
142d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
143d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return          The string converted; {@code null} if error occurs.
144053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
145053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public String toString(int layer) {
146053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        return this.toString(layer, 0, mStringLayer[layer].size() - 1);
147053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
148053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
149053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
150053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Update the upper layer's data.
151053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
152d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer         The base layer
153d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param mod_from      Modified from
154d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param mod_len       Length after modified (# of StrSegments from {@code mod_from})
155d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param org_len       Length before modified (# of StrSegments from {@code mod_from})
156053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
157053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    private void modifyUpper(int layer, int mod_from, int mod_len, int org_len) {
158053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (layer >= MAX_LAYER - 1) {
159053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            /* no layer above */
160053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return;
161053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
162053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
163053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int uplayer = layer + 1;
164053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        ArrayList<StrSegment> strUplayer = mStringLayer[uplayer];
165053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (strUplayer.size() <= 0) {
166053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            /*
167053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project             * if there is no element on above layer,
168053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project             * add a element includes whole elements of the lower layer.
169053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project             */
170053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            strUplayer.add(new StrSegment(toString(layer), 0, mStringLayer[layer].size() - 1));
171053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            modifyUpper(uplayer, 0, 1, 0);
172053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return;
173053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
174053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
175053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int mod_to = mod_from + ((mod_len == 0)? 0 : (mod_len - 1));
176053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int org_to = mod_from + ((org_len == 0)? 0 : (org_len - 1));
177053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        StrSegment last = strUplayer.get(strUplayer.size() - 1);
178053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (last.to < mod_from) {
179053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            /* add at the tail */
180053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            last.to = mod_to;
181053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            last.string = toString(layer, last.from, last.to);
182053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            modifyUpper(uplayer, strUplayer.size()-1, 1, 1);
183053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return;
184053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
185053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
186053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int uplayer_mod_from = -1;
187053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int uplayer_org_to = -1;
188053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int i = 0; i < strUplayer.size(); i++) {
189053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            StrSegment ss = strUplayer.get(i);
190053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            if (ss.from > mod_from) {
191053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                if (ss.to <= org_to) {
192053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    /* the segment is included */
193053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    if (uplayer_mod_from < 0) {
194053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        uplayer_mod_from = i;
195053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    }
196053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    uplayer_org_to = i;
197053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                } else {
198053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    /* included in this segment */
199053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    uplayer_org_to = i;
200053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    break;
201053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                }
202053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            } else {
203053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                if (org_len == 0 && ss.from == mod_from) {
204053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    /* when an element is added */
205053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    uplayer_mod_from = i - 1;
206053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    uplayer_org_to   = i - 1;
207053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    break;
208053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                } else {
209053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    /* start from this segment */
210053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    uplayer_mod_from = i;
211053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    uplayer_org_to = i;
212053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    if (ss.to >= org_to) {
213053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        break;
214053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    }
215053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                }
216053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
217053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
218053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
219053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int diff = mod_len - org_len;
220053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (uplayer_mod_from >= 0) {
221053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            /* update an element */
222053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            StrSegment ss = strUplayer.get(uplayer_mod_from);
223053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            int last_to = ss.to;
224053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            int next = uplayer_mod_from + 1;
225053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            for (int i = next; i <= uplayer_org_to; i++) {
226053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss = strUplayer.get(next);
227053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                if (last_to > ss.to) {
228053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    last_to = ss.to;
229053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                }
230053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                strUplayer.remove(next);
231053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
232053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            ss.to = (last_to < mod_to)? mod_to : (last_to + diff);
233053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
234053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            ss.string = toString(layer, ss.from, ss.to);
235053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
236053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            for (int i = next; i < strUplayer.size(); i++) {
237053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss = strUplayer.get(i);
238053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss.from += diff;
239053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss.to   += diff;
240053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
241053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
242053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            modifyUpper(uplayer, uplayer_mod_from, 1, uplayer_org_to - uplayer_mod_from + 1);
243053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } else {
244053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            /* add an element at the head */
245053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            StrSegment ss = new StrSegment(toString(layer, mod_from, mod_to),
246053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                                           mod_from, mod_to);
247053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            strUplayer.add(0, ss);
248053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            for (int i = 1; i < strUplayer.size(); i++) {
249053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss = strUplayer.get(i);
250053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss.from += diff;
251053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss.to   += diff;
252053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
253053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            modifyUpper(uplayer, 0, 1, 0);
254053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
255053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
256053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        return;
257053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
258053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
259053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
260d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * Insert a {@link StrSegment} at the cursor position.
261053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
262d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * @param layer Layer to insert
263d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * @param str   String
264053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
265053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public void insertStrSegment(int layer, StrSegment str) {
266053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int cursor = mCursor[layer];
267053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        mStringLayer[layer].add(cursor, str);
268053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        modifyUpper(layer, cursor, 1, 0);
269053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        setCursor(layer, cursor + 1);
270053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
271053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
272053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
273d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * Insert a {@link StrSegment} at the cursor position(without merging to the previous segment).
274053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * <p>
275d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer1        Layer to insert
276d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer2        Never merge to the previous segment from {@code layer1} to {@code layer2}.
277d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param str           String
278053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
279053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public void insertStrSegment(int layer1, int layer2, StrSegment str) {
280053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        mStringLayer[layer1].add(mCursor[layer1], str);
281053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        mCursor[layer1]++;
282053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
283053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int i = layer1 + 1; i <= layer2; i++) {
284053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            int pos = mCursor[i-1] - 1;
285053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            StrSegment tmp = new StrSegment(str.string, pos, pos);
286053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            ArrayList<StrSegment> strLayer = mStringLayer[i];
287053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            strLayer.add(mCursor[i], tmp);
288053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[i]++;
289053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            for (int j = mCursor[i]; j < strLayer.size(); j++) {
290053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                StrSegment ss = strLayer.get(j);
291053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss.from++;
292053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss.to++;
293053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
294053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
295053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int cursor = mCursor[layer2];
296053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        modifyUpper(layer2, cursor - 1, 1, 0);
297053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        setCursor(layer2, cursor);
298053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
299053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
300053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
301053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Replace segments at the range specified.
302053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
303d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
304d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param str       String segment array to replace
305d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param from      Replace from
306d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param to        Replace to
307053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
308053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    protected void replaceStrSegment0(int layer, StrSegment[] str, int from, int to) {
309053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        ArrayList<StrSegment> strLayer = mStringLayer[layer];
310053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
311053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (from < 0 || from > strLayer.size()) {
312053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            from = strLayer.size();
313053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
314053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (to < 0 || to > strLayer.size()) {
315053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            to = strLayer.size();
316053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
317053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int i = from; i <= to; i++) {
318053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            strLayer.remove(from);
319053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
320053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int i = str.length - 1; i >= 0; i--) {
321053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            strLayer.add(from, str[i]);
322053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
323053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
324053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        modifyUpper(layer, from, str.length, to - from + 1);
325053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
326053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
327053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
328053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Replace segments at the range specified.
329053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
330d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
331d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param str       String segment array to replace
332d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param num       Size of string segment array
333053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
334053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public void replaceStrSegment(int layer, StrSegment[] str, int num) {
335053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int cursor = mCursor[layer];
336053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        replaceStrSegment0(layer, str, cursor - num, cursor - 1);
337053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        setCursor(layer, cursor + str.length - num);
338053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
339053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
340053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
341053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Replace the segment at the cursor.
342053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
343d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
344d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param str       String segment to replace
345053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
346053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public void replaceStrSegment(int layer, StrSegment[] str) {
347053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int cursor = mCursor[layer];
348053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        replaceStrSegment0(layer, str, cursor - 1, cursor - 1);
349053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        setCursor(layer, cursor + str.length - 1);
350053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
351053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
352053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
353d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * Delete segments.
354053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
355d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * @param layer Layer
356d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * @param from  Delete from
357d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * @param to    Delete to
358053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
359053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public void deleteStrSegment(int layer, int from, int to) {
360053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int[] fromL = new int[] {-1, -1, -1};
361053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int[] toL   = new int[] {-1, -1, -1};
362053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
363053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        ArrayList<StrSegment> strLayer2 = mStringLayer[2];
364053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        ArrayList<StrSegment> strLayer1 = mStringLayer[1];
365053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
366053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (layer == 2) {
367053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            fromL[2] = from;
368053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            toL[2]   = to;
369053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            fromL[1] = strLayer2.get(from).from;
370053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            toL[1]   = strLayer2.get(to).to;
371053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            fromL[0] = strLayer1.get(fromL[1]).from;
372053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            toL[0]   = strLayer1.get(toL[1]).to;
373053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } else if (layer == 1) {
374053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            fromL[1] = from;
375053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            toL[1]   = to;
376053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            fromL[0] = strLayer1.get(from).from;
377053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            toL[0]   = strLayer1.get(to).to;
378053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } else {
379053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            fromL[0] = from;
380053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            toL[0]   = to;
381053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
382053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
383053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int diff = to - from + 1;
384053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int lv = 0; lv < MAX_LAYER; lv++) {
385053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            if (fromL[lv] >= 0) {
386053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                deleteStrSegment0(lv, fromL[lv], toL[lv], diff);
387053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            } else {
388053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                int boundary_from = -1;
389053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                int boundary_to   = -1;
390053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ArrayList<StrSegment> strLayer = mStringLayer[lv];
391053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                for (int i = 0; i < strLayer.size(); i++) {
392053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    StrSegment ss = (StrSegment)strLayer.get(i);
393053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    if ((ss.from >= fromL[lv-1] && ss.from <= toL[lv-1]) ||
394053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        (ss.to >= fromL[lv-1] && ss.to <= toL[lv-1]) ) {
395053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        if (fromL[lv] < 0) {
396053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                            fromL[lv] = i;
397053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                            boundary_from = ss.from;
398053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        }
399053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        toL[lv] = i;
400053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        boundary_to = ss.to;
401053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    } else if (ss.from <= fromL[lv-1] && ss.to >= toL[lv-1]) {
402053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        boundary_from = ss.from;
403053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        boundary_to   = ss.to;
404053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        fromL[lv] = i;
405053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        toL[lv] = i;
406053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        break;
407053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    } else if (ss.from > toL[lv-1]) {
408053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        break;
409053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    }
410053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                }
411053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                if (boundary_from != fromL[lv-1] || boundary_to != toL[lv-1]) {
412053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    deleteStrSegment0(lv, fromL[lv] + 1, toL[lv], diff);
413053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    boundary_to -= diff;
414053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    StrSegment[] tmp = new StrSegment[] {
415053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                        (new StrSegment(toString(lv-1), boundary_from, boundary_to))
416053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    };
417053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    replaceStrSegment0(lv, tmp, fromL[lv], fromL[lv]);
418053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    return;
419053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                } else {
420053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                    deleteStrSegment0(lv, fromL[lv], toL[lv], diff);
421053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                }
422053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
423053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            diff = toL[lv] - fromL[lv] + 1;
424053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
425053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
426053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
427d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa    /**
428d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * Delete segments (internal method).
429d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     *
430d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
431d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param from      Delete from
432d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param to        Delete to
433d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param diff      Differential
434d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     **/
435053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    private void deleteStrSegment0(int layer, int from, int to, int diff) {
436053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        ArrayList<StrSegment> strLayer = mStringLayer[layer];
437053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (diff != 0) {
438053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            for (int i = to + 1; i < strLayer.size(); i++) {
439053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                StrSegment ss = strLayer.get(i);
440053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss.from -= diff;
441053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                ss.to   -= diff;
442053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
443053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
444053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int i = from; i <= to; i++) {
445053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            strLayer.remove(from);
446053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
447053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
448053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
449053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
450053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Delete a segment at the cursor.
451053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
452d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer         Layer
453d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param rightside     {@code true} if direction is rightward at the cursor, {@code false} if direction is leftward at the cursor
454d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return              The number of string segments in the specified layer
455053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
456053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public int delete(int layer, boolean rightside) {
457053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int cursor = mCursor[layer];
458053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        ArrayList<StrSegment> strLayer = mStringLayer[layer];
459053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
460053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (!rightside && cursor > 0) {
461053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            deleteStrSegment(layer, cursor-1, cursor-1);
462053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            setCursor(layer, cursor - 1);
463053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } else if (rightside && cursor < strLayer.size()) {
464053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            deleteStrSegment(layer, cursor, cursor);
465053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            setCursor(layer, cursor);
466053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
467053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        return strLayer.size();
468053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
469053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
470053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
471053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Get the string layer.
472053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
473d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
474d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return          {@link ArrayList} of {@link StrSegment}; {@code null} if error.
475053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
476f96267ad0d85ede52c300ae5456d7e4ecb50915cDaisuke Miyakawa    public ArrayList<StrSegment> getStringLayer(int layer) {
477053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        try {
478053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return mStringLayer[layer];
479053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } catch (Exception ex) {
480053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return null;
481053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
482053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
483053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
484053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
485053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Get upper the segment which includes the position.
486d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     *
487d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
488d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param pos       Position
489d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return      Index of upper segment
490053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
491053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    private int included(int layer, int pos) {
492053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (pos == 0) {
493053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            return 0;
494053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
495053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int uplayer = layer + 1;
496053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int i;
497053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        ArrayList<StrSegment> strLayer = mStringLayer[uplayer];
498053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (i = 0; i < strLayer.size(); i++) {
499053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            StrSegment ss = strLayer.get(i);
500053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            if (ss.from <= pos && pos <= ss.to) {
501053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project                break;
502053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            }
503053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
504053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        return i;
505053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
506053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
507053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
508053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Set the cursor.
509053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
510d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
511d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param pos       Position of cursor
512d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return      New position of cursor
513053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
514053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public int setCursor(int layer, int pos) {
515053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (pos > mStringLayer[layer].size()) {
516053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            pos = mStringLayer[layer].size();
517053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
518053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (pos < 0) {
519053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            pos = 0;
520053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
521053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        if (layer == 0) {
522053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[0] = pos;
523053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[1] = included(0, pos);
524053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[2] = included(1, mCursor[1]);
525053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } else if (layer == 1) {
526053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[2] = included(1, pos);
527053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[1] = pos;
528053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[0] = (pos > 0)? mStringLayer[1].get(pos - 1).to+1 : 0;
529053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        } else {
530053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[2] = pos;
531053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[1] = (pos > 0)? mStringLayer[2].get(pos - 1).to+1 : 0;
532053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[0] = (mCursor[1] > 0)? mStringLayer[1].get(mCursor[1] - 1).to+1 : 0;
533053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
534053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        return pos;
535053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
536053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
537053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
538053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Move the cursor.
539053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
540d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
541d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param diff      Relative position from current cursor position
542d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return      New position of cursor
543053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
544053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public int moveCursor(int layer, int diff) {
545053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        int c = mCursor[layer] + diff;
546053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
547053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        return setCursor(layer, c);
548053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
549053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
550053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
551053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     * Get the cursor position.
552053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
553d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
554d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return cursor   Current position of cursor
555053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
556053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public int getCursor(int layer) {
557053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        return mCursor[layer];
558053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
559053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
560053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
561d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * Get the number of segments.
562053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     *
563d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @param layer     Layer
564d2f2d7241a8f9e02da0930b31b7cb90e4d43423bDaisuke Miyakawa     * @return          Number of segments
565053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     **/
566053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public int size(int layer) {
567053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        return mStringLayer[layer].size();
568053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
569053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project
570053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    /**
571d56eddfd5e0f193359f93e7ef665338cace9e2e9Daisuke Miyakawa     * Clear all information.
572053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project     */
573053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    public void clear() {
574053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        for (int i = 0; i < MAX_LAYER; i++) {
575053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mStringLayer[i].clear();
576053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project            mCursor[i] = 0;
577053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project        }
578053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project    }
579053d50935e0e311286543bd7c535ae2c863c0deThe Android Open Source Project}
580