function netCollection()
{
  var self = this;
  this.classType = "netCollection";
  
  var collection = new Array();
  this.length = collection.length;
  this.id = "Id" + idCnt++;
  this.useBSearch = false;

  this.add = function(obj)
    {
      var i;
      
      for (i = 0; i < collection.length; i++) {
        if (collection[i] == obj) {
//newBodyPara("collection.add: obj "+obj.classType+" already a member");
          return;
          }
        }
        
      collection.push(obj);  
//newBodyPara("collection.add: obj "+obj.classType+" added");
      this.length = collection.length;
    };

  this.remove = function(node)
    {
      var i;
      var left = null, right = null;
  
      if (this.length == 0) return;
    
      for (i = 0; i < collection.length; i++) {
        if (collection[i] == node) {
          if (i > 0) left = collection.slice(0,i);
          if (i < this.length-1) right = collection.slice(i+1,this.length);
          
          delete collection;
          collection = new Array();
          if (left != null) {
            collection = collection.concat(left);
            delete left;
            }
          if (right != null) {
            collection = collection.concat(right);
            delete right;
            }
          this.length = collection.length;
          
          break;
          }
        }
    };

  this.item = function(i)
    {
      if ((i < 0) || (i >= collection.length)) return null;

      return collection[i];
    };  

  this.isMember = function(obj)
    {
      var i;
  
      for (i = 0; i < collection.length; i++) {
//newBodyPara("isMember("+obj.getLId()+" compared to collection["+i+"]="+collection[i].getLId()+" resolves to "+(collection[i] == obj));
        if (collection[i] == obj) return true;
        }
      
      return false;
    };    
    
  this.sort = function(fct)
    {
      collection.sort(fct);
      this.useBSearch = true;
    };

  this.getIdxByLId = function(lid)
    {
      if (!this.useBSearch) return -1;
      if (collection.length == 0) return -1; 
      
      var lbound = 0;
      var ubound = collection.length-1;
      var ptr = Math.floor(ubound/2);
      var lptr = -1;
      
      while (ptr != lptr) {
        var cid = collection[ptr].getLId();
        if (lid == cid) return ptr;
        
        lptr = ptr;
        if (lid < cid) {
          ubound = ptr;
          ptr = Math.floor((lbound+ubound)/2);
          }
        else {
          lbound = ptr;
          ptr = Math.ceil((lbound+ubound)/2);
          }
        }
        
      return -1;
    }
}

function nodesLIdCompare(node1,node2)
{
  return node1.getLId()-node2.getLId();
}

function nodesLeftCompare(node1,node2)
{
  return node1.div.getLeft()-node2.div.getLeft();
}

function netNodesCollection()
{
  var self = this;
  this.classType = "netNodesCollection";
  
  var collection = new netCollection();
  this.length = collection.length;
  this.id = "Id" + idCnt++;
  this.collectionRect = new netRect;

  this.add = function(node)
    {
//newBodyPara("netNodesCollection.add(): node.classType = "+node.classType);    
      collection.add(node);  
      this.length = collection.length;
    };

  this.remove = function(node)
    {
      collection.remove(node);
      this.length = collection.length;
    };

  this.item = function(i)
    {
      return collection.item(i);
    };  

  this.isMember = function(node)
    {
//newBodyPara("netNodesCollection.isMember(): node.classType = "+node.classType);    
      return collection.isMember(node);
    };    

  this.findIdxByLId = function(lId)
    {
      if (collection.useBSearch) {
        return collection.getIdxByLId(lId);
        }
        
      for (var i=0; i < this.length; i++) {  
        if (collection.item(i).getLId() == LId) return i;
        }
    
      return -1;
    };    

  this.isMemberByLId = function(lId)
    {
      return (this.findIdxByLId(lId) != -1);
    };
    
  this.sort = function()
    {
      collection.sort();
    };
    
  this.sortByLId = function()
    {
      collection.sort(nodesLIdCompare);
    };

  this.sortByLeft = function()
    {
      collection.sort(nodesLeftCompare);
    };

  this.netNodesCollection = function()
    {
      var topLeftMostNode;
      var i;

      if (this.length == 0) return null;
      
      topLeftMostNode = collection.item(0);

      for (i=0; i < this.length; i++) {
        if (collection.item(i).div.getTop() < topLeftMostNode.div.getTop()) {
          topLeftMostNode = collection.item(i);
          }
        else if (collection.item(i).div.getTop() == topLeftMostNode.div.getTop()) {
            if (collection.item(i).div.getLeft() < topLeftMostNode.div.getLeft()) {
              topLeftMostNode = collection.item(i); 
            }
          }
        }

      return topLeftMostNode;
    };
  
  this.isEqual = function(other)
    {
      return (this == other);
    };

  this.clearCollectionRect = function() 
    {
      this.collectionRect.left = 0;
      this.collectionRect.top = 0;
      this.collectionRect.width = 0;
      this.collectionRect.height = 0;
    };

  this.calcCollectionRect = function()
    {
      var i;
      var left,top,right,bottom;
      
      this.clearCollectionRect();

      for (i = 0; i < this.length; i++) {
        if ((this.collectionRect.height == 0) && (this.collectionRect.width == 0)) {
          this.collectionRect.fromDiv(collection.item(i).div);
          }
        else {
          if (this.collectionRect.left < collection.item(i).div.getLeft()) left = this.collectionRect.left;
          else                                                             left = collection.item(i).div.getLeft();
          if (this.collectionRect.top < collection.item(i).div.getTop()) top = this.collectionRect.top;
          else                                                           top = collection.item(i).div.getTop();
          if (this.collectionRect.right() > collection.item(i).div.getRight()) right = this.collectionRect.right();
          else                                                                 right = collection.item(i).div.getRight();
          if (this.collectionRect.bottom() > collection.item(i).div.getBottom()) bottom = this.collectionRect.bottom();
          else                                                                   bottom = collection.item(i).div.getBottom();

          this.collectionRect.left = left;
          this.collectionRect.top = top;
          this.collectionRect.width = right-left;
          this.collectionRect.height = bottom-top;  
          }
        }
    };

  this.compare = function(other) 
    {
      return sgn(this.length-other.length);
    };
    
  this.getSpsNodesDisplacement = function(node1,node2)
    {
      if (collection.length) {
        var i1 = 0;
        var i2 = 0;
        for (var i=0; i < collection.length; i++) {
          var o = collection.item(i);
          if (node1 == o) i1 = i;
          if (node2 == o) i2 = i;
          }
        
        return i2-i1;
        }
        
      return 0;
    };
}

