/* This class holds definitions used to make global variables that represent,
   in JavaScript-able form, the pricing information found in the database.
   The object declared in data.js instantiate the classes that are defined here. */


/* This global variable is a 2-dimension array.
   There is one row for each TerrType in the database.
   Each row contains one entry for every territory of that type. */
var terrtypelist = new Array();
for (var i = 0; i < 6; i++)
{
    terrtypelist[i] = new Array();
}


/*  Annotation class */

function AN(anid, antext)
{
    this.id = anid;
    this.text = antext;
}
AN.prototype.toString = function() {
    return "Instance of AN (Annotation) { id: " + this.id + "; text: " + this.text + " }";
}



/*   DurRange class  */
function DR(durid, vl, inc, unt, mult)
{
    this.id = durid;
    // DurRangeID from database
    this.name = vl;
    // Value that appears in select box
    this.incr = inc;
    // Number of days/months/years
    this.unit = unt;
    // Unit of time (day, month, or year)
    this.mult = mult;
    // Price multiplier
}
DR.prototype.toString = function() {
    return "Instance of DR (Duration Range) { id: " + this.id + "; name: " + this.name + "; unit: " + this.unit + "; incr: " + this.incr + "; mult: " + this.mult + "}";
}



/*   DurAxis class  */
function DA(daid)
{
    this.id = daid;
    // DurAxisID from database
    this.durlist = new Array();
    // Array of DR objects
    this.durcount = 0;
    // Size of durlist
}

// Function to add a DurRange to a DurAxis
function DA_ADR(newd)
{
    this.durlist[this.durcount++] = newd;
}
DA.prototype.ADR = DA_ADR;
DA.prototype.toString = function() {
    return "Instance of DA (Duration Axis) { id: " + this.id + "; durcount: " + this.durcount + " }";
}


/*   TerrRange class  */
function TR(tp, pl, mult, newTRID, newTRName)
{
    this.type = tp;
    // Territory type (city, provstate, country etc.)
    this.pricelevel = pl;
    // How expensive it is
    this.mult = mult;
    // Its actual multiplier for categories
    this.id = newTRID;
    this.name = newTRName;
}
TR.prototype.toString = function() {
    return "Instance of TR (Territory Range) { id: " + this.id + "; name: " + this.name + "; type: " + this.type + "; pricelevel: " + this.pricelevel + "; mult: " + this.mult + "}";
}

/*   TerrAxis class  */
function TA(taid)
{
    this.id = taid;
    // TerrAxisID from database
    this.trlist = new Array();
    // Array of TR objects
    this.trcount = 0;
    // Size of trlist
}

// Function to add a TerrRange to a TerrAxis
function TA_ATR(tp, pl, mult, newTRID, newTRName)
{
    var ttm = new TR(tp, pl, mult, newTRID, newTRName);
    this.trlist[this.trcount++] = ttm;
}
TA.prototype.ATR = TA_ATR;
TA.prototype.toString = function() {
    return "Instance of TA (Territory Axis) { id: " + this.id + "; trcount: " + this.trcount + " }";
}

/*   Territory class  */
function T(terrid, vl, tp, pl)
{
    this.id = terrid;
    // TerritoryID from database
    this.name = vl;
    // Name appearing in select box
    this.type = tp;
    // The territory's type
    this.pricelevel = pl;
    // The territory's pricelevel
    this.parentlist = new Array();
    // Array of all direct parents of this territory
    this.parentcount = 0;
    // Size of parentlist
    this.childlist = new Array();
    // Array of all direct children of this territory
    this.childcount = 0;
    // Size of childlist
    terrtypelist[tp][terrtypelist[tp].length] = this;
    // Add this territory to the global terrtypelist object
    this.childIDIndex = new Hashtable();
    //the index containing children ids
}

// Function to add a child to a territory, eg. Canada to North America
function terr_AC(child)
{
    this.childlist[this.childcount++] = child;
    child.parentlist[child.parentcount++] = this;
    this.childIDIndex.set(child.id, true);
}
T.prototype.AC = terr_AC;
T.prototype.toString = function() {
    return "Instance of T (Territory) { id: " + this.id + "; name: " + this.name + "; type: " + this.type + " }";
}



/*   Range class  */
function R(rangeid, vl, mult)
{
    this.id = rangeid;
    // RangeID from database
    this.name = vl;
    // Value to appear in select box
    this.mult = mult;
    // Price multiplier
}
R.prototype.toString = function() {
    return "Instance of R (Range) { id: " + this.id + "; name: " + this.name + "; mult: " + this.mult + " }";
}



/*   Axis class  */
function A(axid, axtitle)
{
    this.id = axid;
    // AxisID from database
    this.title = axtitle;
    // Title to identify the select box
    this.rangelist = new Array();
    // Array of Range objects
    this.rangecount = 0;
    // Size of rangelist
}
A.prototype.toString = function() {
    return "Instance of A (Axis) { id: " + this.id + "; title: " + this.title + "; rangecount: " + this.rangecount + " }";
}

// Function to add a Range to an Axis
function axis_AR(rng)
{
    this.rangelist[this.rangecount++] = rng;
}
A.prototype.AR = axis_AR;


/* Category class  */
function Cat(catid, catname, base, terr, terrax, durax, subname)
{
    this.id = catid;    // CategoryID from database
    this.name = catname;    // Name of category
    this.base = base;    // Base price (0 for categories with no axes)
    this.subname = subname;    // Title to be placed beside list of children,	OR name of divider subcategory
    this.childlist = new Array();    // Array of child Category objects
    this.childcount = 0;    // Size of childlist
    this.lastdivider = 0;    // Number of axes which are 'divider' axes
    this.axislist = new Array();    // Array of Axis objects
    this.axiscount = 0;    // Size of axislist
    this.parent = 0;    // CategoryID of parent
    this.alwaysWorld = terr;    // Whether this category has no territories (i.e. always is World)
    this.isDivider = false;    // Whether this category has a divider axis
    this.durax = durax;    // A DurAxis object representing this category's duration choices
    this.terrax = terrax;    // A TerrAxis object representing this category's territory multipliers
    this.annotationlist = new Array();    // Array of annotations
    this.annotationcount = 0;    // Size of annotationlist
}

// Adds a child to a category
function Cat_AC(child)
{
    this.childlist[this.childcount++] = child;
    child.parent = this;
}
Cat.prototype.AC = Cat_AC;

// Adds a divider child to a category
function Cat_ADC(child, lastdivider)
{
    this.AC(child);
    this.lastdivider = lastdivider;
    child.isDivider = true;
}
Cat.prototype.ADC = Cat_ADC;

// Adds an axis to a category
function Cat_AA(axis)
{
    this.axislist[this.axiscount++] = axis;
}
Cat.prototype.AA = Cat_AA;

// Adds an annotation to a category
function Cat_AAn(ann)
{
    this.annotationlist[this.annotationcount++] = ann;
}
Cat.prototype.AAN = Cat_AAn;
Cat.prototype.toString = function() {
    return "Instance of Cat { id: " + this.id + "; name: " + this.name + "; subname: " + this.subname + "; base: " + this.base + " }";
}


/* DuplPrice class */

function DuplPrice(prceval, disc)
{
    this.val = prceval;
    this.discounted = disc;
}


/*  DuplicateSet class */

function DuplicateSets(duplid, duplActive)
{
    this.id = duplid;
    this.isActive = duplActive;
    this.pricecount = 0;
    this.dblpricelist = new Array();
    this.isdisc = false;
}

function DuplicateSets_APr(price)
{
    var priceobj = new DuplPrice(price, false);
    this.dblpricelist[this.pricecount++] = priceobj;
}
DuplicateSets.prototype.APr = DuplicateSets_APr;


/* Dummy placeholders */
var R0 = new R("R0", "Not specified", 0);
var TA0 = new TA();
var DA0 = new DA();

//Hashtable class
function Hashtable() {
    this.storage = new Object();
    return this;
}
Hashtable.prototype.hasKey = function(key) {
    var undef;
    var item = this.get(key);
    var r = (item == undef) ? false : true;
    return r;
};
Hashtable.prototype.set = function(key, val) {
    this.storage[key]=val;
    //eval("this.storage." + key + " = val");
};
Hashtable.prototype.get = function(key) {
    //var r = eval("this.storage." + key);
    var r = this.storage[key];
    return r;
}
//hashtable test
function _x1_testHashtable() {
    var t = new Hashtable();
    t.set("car1", "honda");
    t.set("car2", "toyota");
    t.set("car3", "dacia");
    t.set(6,12);
    if (t.hasKey("car3") == true && t.hasKey("car4") == false && t.hasKey(6) == true) {
        alert("hasKey OK");
    } else {
        alert("hasKey FAILED!!!");
    }
    if (t.get("car3") == "dacia" && t.get(6) == 12) {
        alert("get/set OK");
    } else {
        alert("get/set FAILED!!!");
    }
}
//_x1_testHashtable();