001    /////////////////////////////////////////////////
002    //This file is part of Sears project.
003    //Subtitle Editor And Re-Synch
004    //A tool to easily modify and resynch movies subtitles.
005    /////////////////////////////////////////////////
006    //This program is free software; 
007    //you can redistribute it and/or modify it under the terms 
008    //of the GNU General Public License 
009    //as published by the Free Software Foundation; 
010    //either version 2 of the License, or (at your option) any later version.
011    /////////////////////////////////////////////////
012    //Sears project is available under sourceforge
013    //at adress: http://sourceforge.net/projects/sears/
014    //Copyright (C) 2005 Booba Skaya
015    //Mail: booba.skaya@gmail.com
016    /////////////////////////////////////////////////
017    
018    // some suggestions about this class: floriaen@gmail.com
019    
020    package sears.search.data;
021    
022    /**
023     * Iterator class for manage int array of char index
024     */
025    public class Window implements Cloneable {
026            
027            private static final int[] NON_NULL_WINDOW = {-1};
028            
029            private int[] window;
030            private int index;
031            private static Window emptyWindow;
032            
033            /**
034             * Constructs an empty window
035             */
036            public Window() {
037                    index = -1;
038                    window = NON_NULL_WINDOW;
039                    emptyWindow = this;
040            }
041            
042            /**
043             * Constructs a window with parameters given
044             * @param text  the text
045             * @param str   the str to search in <tt>text</tt>
046             */
047            public Window(String text, String str) {
048                    setWindowForGettingNextElement(text, str);
049            }
050            
051            /**
052             * Sets a new window
053             * @param text  the text
054             * @param str   the string to search in <tt>text</tt>
055             * @param next  the direction of search
056             */
057            private void setWindow(String text, String str, boolean next) {
058                    if( text == null || str == null ) {
059                            throw new NullPointerException("one or the two string given on parameters is null");
060                    }       
061                    if( text.trim().length() == 0 || str.trim().length() == 0 ) {
062                            // DEVELOPER:
063                            // TODO
064                    }
065                    // format all string
066                    text = formatString(text);
067                    str = formatString(str);
068                    
069                    window = getBeginCharIndexOfAllOccurencesOfStringInText(text,str);
070                    if( next ) {
071                            index = -1;
072                    } else {
073                            index = window.length;
074                    }
075            }
076            
077            /**
078             * Sets a new window
079             * @param text  the text
080             * @param str   the string to search in <tt>text</tt>
081             */
082            public void setWindowForGettingNextElement(String text, String str) {
083                    setWindow(text,str,true);
084            }       
085    
086            /**
087             * Sets a new window
088             * @param text  the text
089             * @param str   the string to search in <tt>text</tt>
090             */
091            public void setWindowForGettingPreviousElement(String text, String str) {
092                    setWindow(text,str,false);
093            }       
094            
095            /**
096             * A char index is always positive, this method returns the next char index
097             * @return the next char index or -1 if there's no next char index
098             */
099            public int getNextCharIndex() {
100                    int charIndex = -1;
101                    if( index + 1 < window.length ) {
102                            charIndex = window[++index];
103                    }
104                    return charIndex;
105            }
106            
107            /**
108             * A char index is always positive, this method returns the previous char index
109             * @return the previous char index or -1 if there's no previous char index
110             */
111            public int getPreviousCharIndex() {
112                    int charIndex = -1;
113                    if( index - 1 >= 0 ) {
114                            charIndex = window[--index];
115                    }
116                    return charIndex;
117            }
118            
119            // CAREFULL: method not synchronized !
120            // text and str could be valid !!!
121            /**
122             * Returns a new window.
123             * @param       text    the text
124             * @param       str             the string to search in <tt>text</tt>
125             * @return                      an array of char index 
126             */
127            private int[] getBeginCharIndexOfAllOccurencesOfStringInText(String text, String str) {
128                    // text is valid 
129                    // DEVELOPPER: text and str could be valid !!!
130                    int[] charIndex;
131                    int indexOf = text.indexOf(str);
132                    // FIRST LOOP, compute array's length,
133                    // take care about the first cell: 'row':
134                    int count = 0;
135                    while( indexOf != -1 ) {
136                            count++;
137                            indexOf = text.indexOf(str, indexOf + 1);
138                    }
139                    charIndex = new int[count];
140                    int lastIndexOf = 0;
141                    // SECOND LOOP, fill the int array:
142                    for( int i=0;i<count;i++) {
143                            charIndex[i] = text.indexOf(str, lastIndexOf);
144                            lastIndexOf = charIndex[i] + 1;
145                    }
146                    return charIndex;
147            }
148            
149            /**
150             * Formats the string given in parameters and returns it:
151             * <ul>
152             * <li> string is convert to lower case </li>
153             * <li> removes all the line separator </li>
154             * </ul>
155             * @param str   the string to format
156             * @return              the formatted string
157             */
158            private String formatString(String str) {
159                    str = str.toLowerCase();
160                    str = str.replaceAll(System.getProperty("line.separator") , " ");
161                    return str;
162            }
163            
164            /*
165             * (non-Javadoc)
166             * @see java.lang.Object#clone()
167             */
168            public Object clone() {
169                    Object clone = null;
170                    try {
171                            clone = super.clone();
172                    } catch (CloneNotSupportedException e) {
173                    }
174                    return clone;
175            }
176            
177            /**
178             * Returns an empty cloned <tt>Window</tt> object
179             * or a new instance if clone method failed
180             * @return an empty cloned <tt>Window</tt> object
181             */
182            public Window getEmptyClonedWindow() {
183                    Window clone = null;
184                    if( emptyWindow == null ) {
185                            emptyWindow = new Window();
186                    } else {
187                            clone = (Window) emptyWindow.clone();
188                            if( clone == null ) {
189                                    clone = new Window();
190                            }
191                    }
192                    return clone;
193            }
194    }