/*
Компилятор языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package ru.malik.elaborarer.avtoo.lang;
import avt.lang.array.*;
import avt.util.*;
public abstract class ProgrammeItem(Object, Cloneable, Measureable, ObjectArray)
{
private ProgrammeItem[] fldChildItemsStore;
private Hashtable fldChildItemsTable;
private ProgrammeItem fldNextItem;
private final String fldSpecialSimpleName;
private final ProgrammeItem fldParentItem;
private final Programme fldParentProgramme;
package (Programme parentProgramme, String specialSimpleName) {
fldSpecialSimpleName = specialSimpleName == null ? null : specialSimpleName.intern();
fldParentProgramme = parentProgramme;
}
package (ProgrammeItem parentItem, String specialSimpleName) {
fldSpecialSimpleName = specialSimpleName;
fldParentItem = parentItem;
fldParentProgramme = parentItem == null ? null : parentItem.fldParentProgramme;
}
public String toString() {
String specialSimpleName = fldSpecialSimpleName;
return specialSimpleName != null ? specialSimpleName : "";
}
public ProgrammeItem getChildItem(String specialSimpleName) {
if(specialSimpleName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "specialSimpleName" }));
}
Hashtable table = fldChildItemsTable;
return table == null ? null : (ProgrammeItem) table[specialSimpleName];
}
public ProgrammeItem getChildItem(String specialSimpleName, boolean ignoreCase) {
if(specialSimpleName == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "specialSimpleName" }));
}
Hashtable table = fldChildItemsTable;
if(table == null)
{
return null;
}
if(!ignoreCase)
{
return (ProgrammeItem) table[specialSimpleName];
}
for(ProgrammeItem[] store = fldChildItemsStore, int length = store.length, int index = 0; index < length; index++)
{
ProgrammeItem item = store[index];
if(specialSimpleName.equalsIgnoreCase(item.fldSpecialSimpleName)) return item;
}
return null;
}
public final int length { read = getLength }
public final String specialSimpleName { read = fldSpecialSimpleName }
public final ProgrammeItem nextItem { read = fldNextItem }
public final ProgrammeItem parentItem { read = fldParentItem }
public final Programme parentProgramme { read = fldParentProgramme }
public ProgrammeItem operator [](int index) {
ProgrammeItem[] store = fldChildItemsStore;
if(store == null)
{
throw new ArrayIndexOutOfBoundsException(avt.lang.package.getResourceString("out-of-bounds.array-index"));
}
return store[index];
}
protected void insertChildItem(ProgrammeItem item, int position) {
if(item == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "item" }));
}
if(item.fldParentProgramme != fldParentProgramme)
{
throw new IllegalArgumentException(package.getResourceString("adding-item.not-same-programme"));
}
ProgrammeItem[] store = fldChildItemsStore;
Hashtable table = fldChildItemsTable;
int length = 0;
if(store == null)
{
fldChildItemsStore = store = new ProgrammeItem[0x0f];
fldChildItemsTable = table = new Hashtable();
}
else if((length = store.length) == store.capacity)
{
if(length == Int.MAX_VALUE)
{
throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
}
Array.copy(store, 0, fldChildItemsStore = store = new ProgrammeItem[length << 1 | 1], 0, length);
}
if(position < 0) position = 0;
if(position > length) position = length;
String name = item.fldSpecialSimpleName;
if(name != null)
{
item.fldNextItem = (ProgrammeItem) table[name];
table[name] = item;
}
store.length = length + 1;
Array.copy(store, position, store, position + 1, length - position);
store[position] = item;
}
protected void removeChildItem(ProgrammeItem item) {
Hashtable table = fldChildItemsTable;
if(item != null && table != null)
{
String name = item.fldSpecialSimpleName;
if(name != null)
{
ProgrammeItem curr = (ProgrammeItem) table[name];
if(curr == item)
{
table[name] = curr.fldNextItem;
}
else if(curr != null) for(ProgrammeItem prev = curr, curr = curr.fldNextItem; curr != null; curr = (prev = curr).fldNextItem) if(curr == item)
{
prev.fldNextItem = curr.fldNextItem;
break;
}
}
Object[] store = fldChildItemsStore;
int length = store.length;
int index = Array.indexOf(item, store, 0, 0);
if(index >= 0)
{
Array.copy(store, index + 1, store, index, --length - index);
store[length] = null;
store.length = length;
}
}
}
protected final void appendChildItem(ProgrammeItem item) { insertChildItem(item, Int.MAX_VALUE); }
private int getLength() {
Object[] store = fldChildItemsStore;
return store == null ? 0 : store.length;
}
}