1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
package Torello.HTML;

import java.util.Vector;
import java.util.Comparator;

/**
 * Allows the NodeSearch Package to simultaneously return both an HTML-{@code Vector} sublist, and
 * the location where that sub-list was located (as an instance of {@link DotPair}) where that
 * sublist was located.
 * 
 * <BR /><BR /><EMBED CLASS='external-html' DATA-FILE-ID=SUB_SECTION>
 * <EMBED CLASS='external-html' DATA-FILE-ID=IMPLEMENTS_REPLACE>
 *
 * @see Torello.HTML.HTMLNode
 * @see Torello.HTML.DotPair
 * @see Torello.HTML.NodeIndex
 * @see Torello.HTML.NodeSearch.TagNodePeekInclusive
 * @see Torello.HTML.NodeSearch.InnerTagPeekInclusive
 */
public class SubSection
    implements CharSequence, java.io.Serializable, Cloneable, Replaceable
{
    // ********************************************************************************************
    // ********************************************************************************************
    // Fields
    // ********************************************************************************************
    // ********************************************************************************************


    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
    public static final long serialVersionUID = 1;

    /**
     * This public field identifies the sub-section location of a particular sub-section from a
     * vectorized-html webpage.  The location of the sub-page is specified by the
     * {@code class DotPair} public-fields:
     * {@code public final int 'start'} and {@code public final int 'end'}
     * 
     * @see DotPair
     */
    public final DotPair location;

    /**
     * This public field identifies the actual nodes - <I><B>the vectorized-html sub-list</B></I> -
     * that are included in this sub-section of an html web-page.
     * 
     * @see HTMLNode
     */
    public Vector<HTMLNode> html;


    // ********************************************************************************************
    // ********************************************************************************************
    // Constructor
    // ********************************************************************************************
    // ********************************************************************************************


    /**
     * This just builds a new instance of this class.  It represents a 'sub-section' of the
     * html-page that needs to encapsulated into an object-instance.  The contents of this
     * data-structure are merely these two parameters that are passed to this constructor.
     *
     * @param location This parameter value will be assigned immediately to the internal-field 
     * {@code public DotPair location.}  It is a two-integer {@code Vector}-index class that points
     * to the starting index-position, inside the main html-{@code Vector}, <I>of the html
     * {@code class 'SubSection'}</I> being constructed here.
     * 
     * @param html This parameter may be any vectorized-html web-page, but
     * <SPAN STYLE="color: red;"><B><I>the intention is that this {@code Vector} is an exact 
     * "cloned range" (a copy of a portion of the web-page) whose starting and ending integer index
     * {@code Vector}-positions are demarcated by the contents of the parameter
     * {@code 'location'}</B></I></SPAN>
     *
     * @throws IllegalArgumentException This exception will throw if either of these two scenarios
     * occur:
     * 
     * <BR /><BR /><UL CLASS=JDUL>
     * <LI>If the input {@code Vector<HTMLNode> 'html'} has {@code html.size() == 0}.</LI>
     * <LI>If {@code html.size() != location.size()}</LI>
     * </UL>
     * 
     * @see SubSection#location
     * @see SubSection#html
     * @see DotPair
     * @see NodeIndex
     * @see HTMLNode
     */
    public SubSection(DotPair location, Vector<HTMLNode> html)
    {
        if (location == null) throw new NullPointerException
            ("Parameter 'DotPair location' to SubSection constructor was null.");

        if (html == null) throw new NullPointerException
            ("Parameter 'Vector<HTMLNode> html' to SubSection constructor was null.");

        if (html.size() == 0) throw new IllegalArgumentException(
            "Parameter 'Vector<HTMLNode> html' to SubSection constructor has size zero, but " +
            "this is not allowed here."
        );

        if (location.size() != html.size()) throw new IllegalArgumentException(
            "Field 'public final int end' [value=" + location.end + "] of passed-parameter " +
            "'DotPair location' to SubSection constructor is different than the length of the " +
            "html-vector [" + html.size() + "]."
        );

        this.location   = location;
        this.html       = html;
    }


    // ********************************************************************************************
    // ********************************************************************************************
    // Misc Interface Methods
    // ********************************************************************************************
    // ********************************************************************************************


    /**
     * Java's {@code interface Cloneable} requirements.  This instantiates a new {@code SubSection}
     * with identical {@code Vector<HTMLNode> html} and {@code DotPair location} fields.
     * 
     * @return A new {@code SubSection} whose internal fields are identical to this one.
     */
    public SubSection clone()
    { return new SubSection(location, html); }

    /**
     * Java's hash-code requirement.
     * 
     * @return A hash-code that may be used when storing this node in a java hashed-collection.
     * The starting location of this {@code SubSection} ought to be be a unique hash
     */
    public int hashCode() { return location.start; }

    /*
     * Java's {@code interface Comparable<T>} requirements.  This does a very simple comparison
     * using the field {@code public DotPair location}.
     * 
     * <BR /><BR /><B><SPAN STYLE="color: red;">FINAL METHOD:</B></SPAN> This method is declared 
     * {@code final}, and cannot be modified by sub-classes.
     * 
     * @param other Another {@code SubSection}, to be compared to {@code 'this' SubSection}
     * 
     * @return An integer that fulfils Java's {@code interface Comparable<T> public boolean
     * compareTo(T t)} method requirements.
     * 
     * @see DotPair#compareTo(DotPair)
     */
    // public final int compareTo(SubSection other)
    // { return this.location.compareTo(other.location); }

    /**
     * This is an "alternative Comparitor" that can be used for sorting instances of this class.
     * It should work with the {@code Collections.sort(List, Comparator)} method in the standard
     * JDK package {@code java.util.*;}
     * 
     * <BR /><BR /><B CLASS=JDDescLabel>Comparator Heuristic:</B>
     * 
     * <BR />This simply compares the {@code public} {@link DotPair}-Typed field
     * {@link #location} to each-other <I>using that class' <B>secondary</B></I> instance of
     * {@code Comparator}.
     * 
     * <BR /><BR />{@code DotPair's} secondary-comparitor may be viewed at: {@link DotPair#comp2}.
     * 
     * @see DotPair#comp2
     */
    public static Comparator<SubSection> comp2 =
        (SubSection ss1, SubSection ss2) -> DotPair.comp2.compare(ss1.location, ss2.location);


    // ********************************************************************************************
    // ********************************************************************************************
    // CharSequence Methods
    // ********************************************************************************************
    // ********************************************************************************************


    /**
     * Java's {@code toString()} requirement.
     * 
     * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B>
     * 
     * <BR />This method is final, and cannot be modified by sub-classes.
     * 
     * @return A {@code String}-representation of this {@code HTMLNode.}
     * 
     * @see #toString()
     */
    public final String toString()
    { return Util.pageToString(html); }

    /**
     * Returns the char value at the specified index of the String defined-by an invokation of the
     * method: {@code Util.pageToString(html)}.
     * An index ranges from {@code '0'} (zero) to {@code length() - 1.} The first {@code char}
     * value of the sequence is at index {@code '0'}, the next at index one, and so on, as for
     * array indexing.
     * 
     * <BR /><BR /><B>NOTE:</B> If the char value specified by the index is a surrogate, the
     * surrogate value is returned.
     * 
     * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B>
     * 
     * <BR />This method is final, and cannot be modified by sub-classes.
     * 
     * @param index The index of the char value to be returned
     * 
     * @return The specified char value
     * 
     * @see #toString()
     */
    public final char charAt(int index)
    { return toString().charAt(index); }

    /**
     * Returns the length of the {@code String} defined-by an invokation of the method:
     * {@code Util.pageToString(html)}.  The length is the number of 16-bit {@code char's} in the
     * sequence.
     * 
     * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B>
     * 
     * <BR />This method is final, and cannot be modified by sub-classes.
     * 
     * @return the number of {@code chars} in {@code this.n.str}
     * 
     * @see #toString()
     */
    public final int length() { return toString().length(); }

    /**
     * Returns a {@code java.lang.CharSequence} that is a subsequence of the {@code String}
     * defined-by an invokation of the method: {@code Util.pageToString(html)}.  The subsequence
     * starts with the {@code char} value at the specified index and ends with the {@code char}
     * value at index {@code end - 1.}  The length (in {@code char's}) of the returned sequence is
     * {@code end - start}, so if {@code start == end} then an empty sequence is returned.
     * 
     * <BR /><BR /><B CLASS=JDDescLabel>Final Method:</B>
     * 
     * <BR />This method is final, and cannot be modified by sub-classes.
     * 
     * @param start The start index, inclusive
     * @param end The end index, exclusive
     * 
     * @return The specified subsequence
     * 
     * @see #toString()
     */
    public final CharSequence subSequence(int start, int end)
    { return toString().substring(start, end); }


    // ********************************************************************************************
    // ********************************************************************************************
    // Replaceable Methods
    // ********************************************************************************************
    // ********************************************************************************************


    // All of these "Inherit" the Replaceable-Interface Comments by javadoc.  There is no need
    // to retype the description that is already going to be there when JavaDoc does its thing

    public int originalSize()           { return location.size(); }
    public int currentSize()            { return html.size(); }
    public int originalLocationStart()  { return location.start; }
    public int originalLocationEnd()    { return location.end + 1; }


    public Vector<HTMLNode> currentNodes() { return html; }

    public HTMLNode firstCurrentNode()
    { return currentNodes().elementAt(0); }

    public HTMLNode lastCurrentNode()
    { return html.elementAt(html.size() - 1); }


    public boolean addAllInto(Vector<HTMLNode> fileVec)
    { return fileVec.addAll(html); }

    public boolean addAllInto(int index, Vector<HTMLNode> fileVec)
    { return fileVec.addAll(index, html); }

    public int update(Vector<HTMLNode> originalHTML)
    { return ReplaceNodes.r(originalHTML, location, html); }
}