// Index test record
function IndexTestRecord(nodeName, coef)
{
  this.m_nodeName = nodeName;
  this.m_stdNodeName = nodeName;
  this.m_coef = coef;
}

function Index2TestRecord(nodeName, stdNodeName, coef)
{
  this.m_nodeName = nodeName;
  this.m_stdNodeName = stdNodeName;
  this.m_coef = coef;
}

// Index calculator
//  base
function IndexCalculator(name, nodeName, secName, pTestsList)
{
  this.m_name = name;
  this.m_nodeName = nodeName;
  this.m_secName = secName;
  this.m_stdSecName = secName;
  this.m_pList = pTestsList;
  this.m_nValue = null;
  this.Clear = _IndexCalculator_Clear;
  this.DoCalculate = _IndexCalculator_DoCalculate;
  this.Calculate = _IndexCalculator_Calculate;
}

// Index calculator
//  Spb
function SpbIndexCalculator()
{
  this.m_name = "Spb Benchmark index";
  this.m_nodeName = "index-spb";
  this.m_nValue = null;
  this.Clear = _IndexCalculator_Clear;
  this.Calculate = _SpbIndexCalculator_Calculate;
}

// Index calculator
//  Platform
function PlatformIndexCalculator()
{
  this.m_name = "Platform index";
  this.m_nodeName = "index-platform";
  this.m_nValue = null;
  this.Clear = _IndexCalculator_Clear;
  this.Calculate = _PlatformIndexCalculator_Calculate;
}

// implementation
function _IndexCalculator_Clear()
{
  this.m_nValue = null;
}

function _IndexCalculator_DoCalculate(pParentSec, pStdParentSec)
{
  if (!pParentSec || !pStdParentSec)
    return -1;

  var dSum = 0.0;

  for (var i = 0; i < this.m_pList.length; i++)
  {
    var pRecord = this.m_pList[i];
    var pTestSec = pParentSec.selectSingleNode(pRecord.m_nodeName);
    var pStdTestSec = pStdParentSec.selectSingleNode(pRecord.m_stdNodeName);

    if (!pTestSec || !pStdTestSec)
      return -1;

    var nValue = parseFloat(pTestSec.text);
    var nStdValue = parseFloat(pStdTestSec.text);

    if (isNaN(nValue) || nValue <= 0 || isNaN(nStdValue) || nStdValue <= 0)
      return -1;

    dSum += pRecord.m_coef * nValue * 1.0 / nStdValue;
  }

  return 100000.0 / dSum;
}

function _IndexCalculator_Calculate(pRootSec, pStdRootSec)
{
  if (this.m_nValue != null)
    return this.m_nValue;

  this.m_nValue = -1;  

  var pParentSec = pRootSec.selectSingleNode(this.m_secName);
  var pStdParentSec = pStdRootSec.selectSingleNode(this.m_stdSecName);

  if (!pParentSec || !pStdParentSec)
    return -1;

  this.m_nValue = this.DoCalculate(pParentSec, pStdParentSec);

  return this.m_nValue;
}

// instances of the indexes
var g_pFileSystemIndex = new IndexCalculator("File system index", "index-filesystem", "main-tests",
  new Array(
    new IndexTestRecord("fs-largefilewrite", 10),
    new IndexTestRecord("fs-largefileread", 20),
    new IndexTestRecord("fs-largefilecopy", 10),
    new IndexTestRecord("fs-manyfileswrite", 10),
    new IndexTestRecord("fs-manyfilesread", 20),
    new IndexTestRecord("fs-manyfilescopy", 15),
    new IndexTestRecord("fs-dirlisting", 5),
    new IndexTestRecord("fs-db", 10)
  )
);

var g_pGraphicsIndex = new IndexCalculator("Graphics index", "index-graphics", "main-tests",
  new Array(
    new IndexTestRecord("grf-ddb", 40),
    new IndexTestRecord("grf-dib", 20),
    new IndexTestRecord("grf-gapi", 40)
  )
);  

var g_pCPUIndex = new IndexCalculator("CPU index", "index-cpu", "main-tests",
  new Array(
    new IndexTestRecord("misc-zip", 30),
    new IndexTestRecord("misc-jpeg", 30),
    new IndexTestRecord("misc-mwips", 15),
    new IndexTestRecord("misc-memcpy", 25)
  )
);

var g_pArkaballIndex = new IndexCalculator("Arkaball index", "index-arkaball", "main-tests",
  new Array(
    new IndexTestRecord("misc-arkaball", 100)
  )  
);

var g_pBuiltInIndex = new IndexCalculator("Built-in index", "index-builtin", "main-tests",
  new Array(
    new IndexTestRecord("builtin-pw", 40),
    new IndexTestRecord("builtin-pie-html", 25),
    new IndexTestRecord("builtin-pie-jpeg", 10),
    new IndexTestRecord("builtin-fe", 25)
  )
);

var g_pActiveSyncIndex = new IndexCalculator("ActiveSync index", "index-activesync", "main-tests",
  new Array(
    new IndexTestRecord("acs-write", 65),
    new IndexTestRecord("acs-read", 35)
  )
);

var g_pStorageCardIndex = new IndexCalculator("Storage card index", "index-storagecard", "main-tests",
  new Array(
    new Index2TestRecord("sc-largefilewrite", "fs-largefilewrite", 20),
    new Index2TestRecord("sc-largefileread", "fs-largefileread", 30),
    new Index2TestRecord("sc-manyfileswrite", "fs-manyfileswrite", 15),
    new Index2TestRecord("sc-manyfilesread", "fs-manyfilesread", 25),
    new Index2TestRecord("sc-dirlisting", "fs-dirlisting", 10)
  )  
);

var g_pSpbIndex = new SpbIndexCalculator();

var g_pPlatformIndex = new PlatformIndexCalculator();

// implementation of SpbIndexCalculator
function _SpbIndexCalculator_Calculate(pRootSec, pStdRootSec)
{
  if (this.m_nValue != null)
    return this.m_nValue;

  this.m_nValue = -1;  

  var dSum = 0.0;

// CPU
  var nIndex = g_pCPUIndex.Calculate(pRootSec, pStdRootSec);

  if (nIndex < 0)
    return -1;

  dSum += 50.0 / nIndex;

// File system
  nIndex = g_pFileSystemIndex.Calculate(pRootSec, pStdRootSec);

  if (nIndex < 0)
    return -1;

  dSum += 35.0 / nIndex;

// Graphics
  nIndex = g_pGraphicsIndex.Calculate(pRootSec, pStdRootSec);

  if (nIndex < 0)
    return -1;

  dSum += 10.0 / nIndex;

// Arkaball
  nIndex = g_pArkaballIndex.Calculate(pRootSec, pStdRootSec);

  if (nIndex < 0)
    return -1;

  dSum += 5.0 / nIndex;

  this.m_nValue = 100.0 / dSum;

  return this.m_nValue;
}

// implementation of PlatformIndexCalculator
function _PlatformIndexCalculator_Calculate(pRootSec, pStdRootSec)
{
  if (this.m_nValue != null)
    return this.m_nValue;

  this.m_nValue = -1;  

  var dSum = 0.0;

// BuiltIn
  var nIndex = g_pBuiltInIndex.Calculate(pRootSec, pStdRootSec);

  if (nIndex < 0)
    return -1;

  dSum += 50.0 / nIndex;

// Spb
  nIndex = g_pSpbIndex.Calculate(pRootSec, pStdRootSec);

  if (nIndex < 0)
    return -1;

  dSum += 50.0 / nIndex;

  this.m_nValue = 100.0 / dSum;

  return this.m_nValue;
}

function ClearIndexes()
{
  g_pFileSystemIndex.Clear();
  g_pGraphicsIndex.Clear();
  g_pCPUIndex.Clear();
  g_pArkaballIndex.Clear();
  g_pBuiltInIndex.Clear();
  g_pActiveSyncIndex.Clear();
  g_pStorageCardIndex.Clear();
  g_pSpbIndex.Clear();
  g_pPlatformIndex.Clear();
}

var g_pIndexes = new Array(
  g_pSpbIndex,
  g_pCPUIndex,
  g_pFileSystemIndex,
  g_pGraphicsIndex,
  g_pActiveSyncIndex,
  g_pPlatformIndex
);

