package com.planet_ink.coffee_mud.Common;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;
import java.util.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
public class DefaultRoomnumberSet implements RoomnumberSet
{
public DVector root=new DVector(2);
public String ID(){return "DefaultRoomnumberSet";}
public int compareTo(Object o){ return CMClass.classID(this).compareToIgnoreCase(CMClass.classID(o));}
public CMObject newInstance(){try{return (CMObject)getClass().newInstance();}catch(Exception e){return new DefaultRoomnumberSet();}}
public void initializeClass(){}
public CMObject copyOf()
{
DefaultRoomnumberSet R=new DefaultRoomnumberSet();
R.root=new DVector(2);
CMIntegerGrouper CI=null;
for(int r=0;r<root.size();r++)
{
CI=((CMIntegerGrouper)root.elementAt(r,2));
R.root.addElement(root.elementAt(r,1),CI==null?null:CI.copyOf());
}
return R;
}
public void add(RoomnumberSet set)
{
Vector V=set.getAreaNames();
CMIntegerGrouper his=null;
CMIntegerGrouper mine=null;
String arName=null;
for(int v=0;v<V.size();v++)
{
arName=(String)V.elementAt(v);
his=set.getGrouper(arName);
mine=set.getGrouper(arName);
if(mine==null)
{
if(his!=null)
mine=(CMIntegerGrouper)his.copyOf();
root.addElement(arName.toUpperCase(),mine);
}
else
mine.add(his);
}
}
public void remove(String str)
{
String areaName=str.toUpperCase().trim();
if(areaName.length()==0) return;
String theRest=null;
long roomNum=-1;
int x=areaName.indexOf("#");
CMIntegerGrouper CI=null;
if(x<=0)
CI=getGrouper(areaName);
else
if(x>0)
{
theRest=areaName.substring(x+1).trim();
areaName=areaName.substring(0,x);
CI=getGrouper(areaName);
if(CI==null) return;
x=theRest.indexOf("#(");
if((x>=0)&&(theRest.endsWith(")"))&&(CMath.isInteger(theRest.substring(0,x))))
{
int comma=theRest.indexOf(",",x);
if(comma>0)
{
roomNum=(Long.parseLong(theRest.substring(0,x))<<30);
roomNum+=(Long.parseLong(theRest.substring(x+2,comma))<<15);
roomNum+=Long.parseLong(theRest.substring(comma+1,theRest.length()-1));
if(roomNum<CMIntegerGrouper.NEXT_BITS) roomNum|=CMIntegerGrouper.GRID_FLAGL;
}
}
else
if(CMath.isInteger(theRest))
roomNum=Integer.parseInt(theRest.substring(x+1).trim());
}
if(CI==null) return;
CI.remove(roomNum);
if(CI.roomCount()==0)
root.removeElement(areaName.toUpperCase());
}
public void remove(RoomnumberSet set)
{
}
public int roomCountAllAreas()
{
int total=0;
CMIntegerGrouper CMI=null;
for(int i=0;i<root.size();i++)
{
CMI=(CMIntegerGrouper)root.elementAt(i,2);
if(CMI==null)
total++;
else
total+=CMI.roomCount();
}
return total;
}
public int roomCount(String prefix)
{
prefix=prefix.toUpperCase();
int x=prefix.indexOf("#");
if(x>0)
prefix=prefix.substring(0,x);
int start=0;
int end=root.size()-1;
int comp=-1;
int mid=-1;
while(start<=end)
{
mid=(end+start)/2;
comp=prefix.compareTo((String)root.elementAt(mid,1));
if(comp==0)
{
if(root.elementAt(mid,2)!=null)
{
CMIntegerGrouper CMI=(CMIntegerGrouper)root.elementAt(mid,2);
if(CMI==null) return 1;
return CMI.roomCount();
}
return 0;
}
else
if(comp<0)
end=mid-1;
else
start=mid+1;
}
return 0;
}
public String random()
{
int total=0;
CMIntegerGrouper CMI=null;
for(int i=0;i<root.size();i++)
{
CMI=(CMIntegerGrouper)root.elementAt(i,2);
if(CMI==null)
total++;
else
total+=CMI.roomCount();
}
if(total<=0) return null;
int which=CMLib.dice().roll(1,total,-1);
total=0;
String roomID=null;
for(int i=0;i<root.size();i++)
{
CMI=(CMIntegerGrouper)root.elementAt(i,2);
if(CMI==null)
total++;
else
total+=CMI.roomCount();
if(which<total)
{
roomID=(String)root.elementAt(i,1);
break;
}
}
if(roomID==null) return null;
if(CMI==null)
{
//Log.errOut("RNUMS","Unable to even select an integer group! Picked "+which+"/"+grandTotal);
return roomID;
}
long selection=CMI.random();
return convertRoomID(roomID,selection);
}
public int[] convertRoomID(long coded)
{
if(coded==-1) return null;
int[] ids=new int[3];
ids[1]=-1;
ids[2]=-1;
if(coded<=CMIntegerGrouper.NEXT_BITS)
{
ids[0]=(int)coded;
return ids;
}
long mask=0;
for(int i=0;i<15;i++) mask=(mask<<1)+1;
ids[2]=(int)(coded&mask);
long mask2=mask<<15;
ids[1]=(int)((coded&mask2)>>15);
mask|=mask2;
mask=mask<<30;
ids[0]=(int)(((coded&mask)>>30)&(CMIntegerGrouper.NEXT_BITSL-CMIntegerGrouper.GRID_FLAGL));
return ids;
}
public String convertRoomID(String prefix, long coded)
{
if(coded==-1) return prefix;
if(coded<CMIntegerGrouper.NEXT_BITS)
return prefix+"#"+coded;
long mask=0;
for(int i=0;i<15;i++) mask=(mask<<1)+1;
long thirdID=coded&mask;
long mask2=mask<<15;
long secondID=(coded&mask2)>>15;
mask|=mask2;
mask=mask<<30;
long firstID=(((coded&mask)>>30)&(CMIntegerGrouper.NEXT_BITSL-CMIntegerGrouper.GRID_FLAGL));
return prefix+"#"+firstID+"#("+secondID+","+thirdID+")";
}
public Vector getAreaNames(){ return (Vector)root.getDimensionVector(1).clone();}
private boolean isGrouper(String areaName)
{
areaName=areaName.toUpperCase();
int start=0;
int end=root.size()-1;
int comp=-1;
int mid=-1;
while(start<=end)
{
mid=(end+start)/2;
comp=areaName.compareTo((String)root.elementAt(mid,1));
if(comp==0) return true;
else
if(comp<0)
end=mid-1;
else
start=mid+1;
}
return false;
}
public CMIntegerGrouper getGrouper(String areaName)
{
areaName=areaName.toUpperCase();
int start=0;
int end=root.size()-1;
int comp=-1;
int mid=-1;
while(start<=end)
{
mid=(end+start)/2;
comp=areaName.compareTo((String)root.elementAt(mid,1));
if(comp==0)
{
if(root.elementAt(mid,2)!=null)
return ((CMIntegerGrouper)root.elementAt(mid,2));
return null;
}
else
if(comp<0)
end=mid-1;
else
start=mid+1;
}
return null;
}
public boolean contains(String str)
{
if(str==null) return false;
String theRest=null;
long roomNum=-1;
int origX=str.indexOf("#");
int x=origX;
if(x>0)
{
theRest=str.substring(x+1).trim();
str=str.substring(0,x);
x=theRest.indexOf("#(");
if((x>=0)&&(theRest.endsWith(")"))&&(CMath.isInteger(theRest.substring(0,x))))
{
int comma=theRest.indexOf(",",x);
if(comma>0)
{
roomNum=Long.parseLong(theRest.substring(0,x))<<30;
roomNum+=(Long.parseLong(theRest.substring(x+2,comma))<<15);
roomNum+=Long.parseLong(theRest.substring(comma+1,theRest.length()-1));
if(roomNum<CMIntegerGrouper.NEXT_BITS) roomNum|=CMIntegerGrouper.GRID_FLAGL;
}
}
else
if(CMath.isInteger(theRest))
roomNum=Integer.parseInt(theRest.substring(x+1).trim());
}
CMIntegerGrouper myGrouper=getGrouper(str);
if((origX<0)&&(myGrouper==null)&&(isGrouper(str)))
return true;
if(myGrouper==null) return false;
return myGrouper.contains(roomNum);
}
public String xml()
{
StringBuffer str=new StringBuffer("<AREAS>");
for(int i=0;i<root.size();i++)
{
str.append("<AREA><ID>"+(String)root.elementAt(i,1)+"</ID>");
if(root.elementAt(i,2)!=null)
str.append("<NUMS>"+((CMIntegerGrouper)root.elementAt(i,2)).text()+"</NUMS>");
str.append("</AREA>");
}
return str.toString()+"</AREAS>";
}
public void parseXML(String xml)
{
Vector V=CMLib.xml().parseAllXML(xml);
if((V==null)||(V.size()==0)) return;
Vector xV=CMLib.xml().getRealContentsFromPieces(V,"AREAS");
root.clear();
String ID=null;
String NUMS=null;
if((xV!=null)&&(xV.size()>0))
for(int x=0;x<xV.size();x++)
{
XMLLibrary.XMLpiece ablk=(XMLLibrary.XMLpiece)xV.elementAt(x);
if((ablk.tag.equalsIgnoreCase("AREA"))&&(ablk.contents!=null))
{
ID=CMLib.xml().getValFromPieces(ablk.contents,"ID");
NUMS=CMLib.xml().getValFromPieces(ablk.contents,"NUMS");
if((NUMS!=null)&&(NUMS.length()>0))
root.addElement(ID,((CMIntegerGrouper)CMClass.getCommon("DefaultCMIntegerGrouper")).parseText(NUMS));
else
root.addElement(ID,null);
}
}
}
public void add(String str)
{
String areaName=str.toUpperCase().trim();
if(areaName.length()==0) return;
String theRest=null;
long roomNum=-1;
int x=areaName.indexOf("#");
if(x>0)
{
theRest=areaName.substring(x+1).trim();
areaName=areaName.substring(0,x);
x=theRest.indexOf("#(");
if((x>=0)&&(theRest.endsWith(")"))&&(CMath.isInteger(theRest.substring(0,x))))
{
int comma=theRest.indexOf(",",x);
if(comma>0)
{
roomNum=(Long.parseLong(theRest.substring(0,x))<<30);
roomNum+=(Long.parseLong(theRest.substring(x+2,comma))<<15);
roomNum+=Long.parseLong(theRest.substring(comma+1,theRest.length()-1));
if(roomNum<CMIntegerGrouper.NEXT_BITS) roomNum|=CMIntegerGrouper.GRID_FLAGL;
}
}
else
if(CMath.isInteger(theRest))
roomNum=Integer.parseInt(theRest.substring(x+1).trim());
}
int start=0;
int end=root.size()-1;
int comp=-1;
int mid=-1;
int lastStart=0;
int lastEnd=root.size()-1;
while(start<=end)
{
mid=(end+start)/2;
comp=areaName.compareTo((String)root.elementAt(mid,1));
if(comp==0)
break;
else
if(comp<0)
{
lastEnd=end;
end=mid-1;
}
else
{
lastStart=start;
start=mid+1;
}
}
if(comp==0)
{
if(root.elementAt(mid,2)!=null)
((CMIntegerGrouper)root.elementAt(mid,2)).add(roomNum);
}
else
{
if(mid<0)
root.addElement(areaName,((CMIntegerGrouper)CMClass.getCommon("DefaultCMIntegerGrouper")).add(roomNum));
else
{
for(comp=lastStart;comp<=lastEnd;comp++)
if(areaName.compareTo((String)root.elementAt(comp,1))<0)
{
root.insertElementAt(comp,areaName,((CMIntegerGrouper)CMClass.getCommon("DefaultCMIntegerGrouper")).add(roomNum));
return;
}
root.addElement(areaName,((CMIntegerGrouper)CMClass.getCommon("DefaultCMIntegerGrouper")).add(roomNum));
}
}
}
public Enumeration getRoomIDs(){return new RoomnumberSetEnumeration();}
private class RoomnumberSetEnumeration implements Enumeration
{
Vector areaNames=null;
String areaName=null;
long[] nums=null;
String nextID=null;
int n=0;
public RoomnumberSetEnumeration(){ areaNames=getAreaNames();}
public boolean hasMoreElements(){
if(nextID==null) getNextID();
return nextID!=null;
}
public Object nextElement(){
if(nextID==null) getNextID();
String next=nextID;
nextID=null;
return next;
}
private void getNextID()
{
if(nums==null)
{
nextID=null;
if((areaNames==null)||(areaNames.size()==0))
return;
areaName=(String)areaNames.elementAt(0);
areaNames.removeElementAt(0);
CMIntegerGrouper grp=getGrouper(areaName);
if(grp==null){ nextID=areaName; return;}
nums=grp.allRoomNums();
n=0;
}
if((nums==null)||(n>=nums.length))
{
nums=null;
getNextID();
return;
}
long num=nums[n++];
nextID=convertRoomID(areaName,num);
}
}
}