subclass(RecordListViewTreeGrid, RecordListView);
function RecordListViewTreeGrid(id)
{
  RecordListView.call(this, id);

  // Indicates whether or not we are to force a reload of the tree
  // data after a drag+drop operation - this is necessary if the drag
  // and drop changes the structure of the tree as in the department 
  // list screen.
  this.ReloadTreeOnDragDrop = false;
  
  this.tree = new RecordListTree(id + "_tree");
  this.treePanel = new RecordListPanel(id + "_treePanel", "Tree", "style_"+id);
  this.treePanel.setChildContent(this.tree);
  this.treePanel.setWidth(250);

  this.searchPanel = new RecordListPanel(id + "_searchPanel", "Search", "style_"+id);
  this.searchPanel.setChildContent(this.search);
  this.searchPanel.setWidth(250);
  this.searchPanel.setBelowPanel(this.treePanel);
  
  this.dataGridPanel.setLeftPanel(this.treePanel);

  this.defaultSelectedNodeKey = null;
  this.selectedNodeKey = null;
  this.dragField = null;

  this.treeDataCommand = null;
  this.gridDataCommand = null;
  this.moveRecordsCommand = null;
  this.updateViewDownCommand = null;
}

RecordListViewTreeGrid.prototype.init = function(parent)
{
  RecordListView.prototype.init.call(this, parent);
  
  this.treePanel.init(this);
  this.searchPanel.init(this);
  
  this.refreshTree = true;
  this.refreshItems = true;

  this.tree.onDrop.addEventListener(new REventListener(this.onDropListener, this));
  this.dataGrid.onDragStart.addEventListener(new REventListener(this.onDragStart, this));
  this.tree.onSelectItem.addEventListener(new REventListener(this.onSelectItemListener, this));
  this.parent.onRecordModify.addEventListener(new REventListener(this.onRecordModifyListener, this));
  this.parent.onReLayout.addEventListener(new REventListener(this.onReLayoutListener, this));
  this.onShow.addEventListener(new REventListener(this.onShowListener, this));
  this.searchPanel.onExpandCollapse.addEventListener(new REventListener(this.onReLayoutListener, this));
  this.search.onSearch.addEventListener(new REventListener(this.onSearchListener, this));
  this.search.onReset.addEventListener(new REventListener(this.onSearchResetListener, this));
  this.tree.onViewDownChange.addEventListener(new REventListener(this.onViewDownChangeListener, this));
}

RecordListViewTreeGrid.prototype.attach = function(node)
{
  this.treePanel.attach(node);
  this.searchPanel.attach(node);
  this.dataGridPanel.attach(node);
}

RecordListViewTreeGrid.prototype.onReLayoutListener = function()
{
  this.treePanel.resize();
  this.searchPanel.resize();
  this.dataGridPanel.resize();
}

RecordListViewTreeGrid.prototype.onRecordModifyListener = function()
{
  if (this.parent.getCurrentView() == this)
    this.requestItems();
  else
    this.refreshItems = true;

  // If this was triggered as the result of a drop AND if the
  // ReloadTreeOnDragDrop flag is set, force a reload of
  // the tree data:
  if (this.dropInProgress && this.ReloadTreeOnDragDrop)
  {
    // Clear out existing tree data:    
    this.tree.rootNodeList = new Array();
    this.tree.nodeMap = new Object();
    this.tree.nodeImageMap = new Object();
    
    // Reload
    this.requestTree();
  }
    
  this.dropInProgress = false;
}

RecordListViewTreeGrid.prototype.onShowListener = function()
{
  if (this.refreshTree)
  {
    this.requestTree();
    this.refreshTree = false;
  }
  else if (!this.refreshItems)
  {
    this.onDataChange.trigger(this.totalRows, this.getStartIndex());
  }
}

RecordListViewTreeGrid.prototype.setTreeTitle = function(title)
{
  this.treePanel.setTitle(title);
}

RecordListViewTreeGrid.prototype.setDefaultSelectedNodeKey = function(id)
{
  this.defaultSelectedNodeKey = id;
}

RecordListViewTreeGrid.prototype.setSelectedNodeKey = function(id)
{
  this.selectedNodeKey = id;
}

RecordListViewTreeGrid.prototype.setDragField = function(field)
{
  this.dragField = field;
}

RecordListViewTreeGrid.prototype.setReloadTreeOnDragDrop = function(value)
{
    this.ReloadTreeOnDragDrop = value;
}

RecordListViewTreeGrid.prototype.setTreeDataCommand = function(command)
{
  this.treeDataCommand = command;
}

RecordListViewTreeGrid.prototype.setMoveRecordsCommand = function(command)
{
  this.moveRecordsCommand = command;
}

RecordListViewTreeGrid.prototype.setUpdateViewDownCommand = function(command)
{
  this.updateViewDownCommand = command;
}

RecordListViewTreeGrid.prototype.getSelectedContainerNodeId = function()
{
  return this.tree.getSelectedNodeKey();
}

RecordListViewTreeGrid.prototype.setEnableViewDown = function(enableViewDown)
{
  this.tree.setEnableViewDown(enableViewDown);
}

RecordListViewTreeGrid.prototype.setViewDown = function(viewDown)
{
  this.tree.setViewDown(viewDown);
}

RecordListViewTreeGrid.prototype.requestTree = function()
{
  var command = this.treeDataCommand;
  this.postCommand(command, new REventListener(this.onTreeLoad, this));
}

// jsObject is an array of items
//   where each item is a generic representation of a tuple (constructed by json)
RecordListViewTreeGrid.prototype.onTreeLoad = function(jsObject, params)
{
  this.createTree(jsObject.rows);

  var node = null
  if (null != this.selectedNodeKey)
    node = this.tree.getNode(this.selectedNodeKey);
  if (null == node && null != this.defaultSelectedNodeKey)
    node = this.tree.getNode(this.defaultSelectedNodeKey);
  if (null == node)
    node = this.tree.getRootNode();
  if (node)
    this.selectedTreeNode(node);
}

RecordListViewTreeGrid.prototype.createTree = function(rows)
{
  for (var i=0; i<rows.length; i++)
  {
    var treeNode = rows[i];
    var bReadOnly = false;
    if(treeNode.ReadOnly == "1") bReadOnly = true;
    
    var bDisabled = false;
    if(treeNode.Disabled == "1" ) bDisabled = true;
           
    this.tree.addNode( treeNode.Id, treeNode.ParentId, treeNode.Name, null, bReadOnly, bDisabled);
  }
  this.tree.refresh();
}

RecordListViewTreeGrid.prototype.onSelectItemListener = function(selected, id)
{
  if (selected)
    this.requestItems();
}

RecordListViewTreeGrid.prototype.requestItems = function()
{
  var nodeId = this.tree.getSelectedNodeKey();

  // remember the last selected node
  if("search" != nodeId)
    this.selectedNodeKey = nodeId;

  if (null != nodeId)
  {
    this.dataGrid.displayWaiting("Loading...");
    this.dataGrid.removeColumn(this.hierarchyColumnField, this.hierarchyColumnText);
    if ("search"==nodeId || this.tree.getViewDown())
      this.dataGrid.addColumn(this.hierarchyColumnField, this.hierarchyColumnText, this.hierarchyColumnPosition);
    var command = this.gridDataCommand + "," + this.getStartIndex() + "," + nodeId;
    this.postCommand(command, new REventListener(this.onItemsLoad, this));
    this.refreshItems = false;
  }
}

RecordListViewTreeGrid.prototype.onViewDownChangeListener = function()
{
  var nodeId = this.tree.getSelectedNodeKey();
  if (null != nodeId)
  {
    this.dataGrid.displayWaiting("Loading...");
    this.dataGrid.removeColumn(this.hierarchyColumnField, this.hierarchyColumnText);
    if ("search"==nodeId || this.tree.getViewDown())
      this.dataGrid.addColumn(this.hierarchyColumnField, this.hierarchyColumnText, this.hierarchyColumnPosition);
    var command = this.updateViewDownCommand + "," + (this.tree.getViewDown()?'1':'0');
    this.postCommand(command, new REventListener(this.onItemsLoad, this));
    this.refreshItems = false;
  }
}


RecordListViewTreeGrid.prototype.selectedTreeNode = function(node)
{
  this.tree.setSelectedNodeKey(node.getId());
  //fixme: make sure the tree panel is scrolled so that the selected tree node is showing
}

RecordListViewTreeGrid.prototype.onDropListener = function(dragObject, dropObject)
{
  if ("search"==dropObject.id)
    return;

  if (dropObject.bReadOnly == true)
  {
    //rkrk
    if(!IsNullOrUndefined(RecordListViewTreeGrid.statics))
        alert(RecordListViewTreeGrid.statics.g_textModifyDepartmentNoPermission);
    return;
  }

  var fromNodeId = this.tree.getSelectedNodeKey();
  
  var command = this.moveRecordsCommand + "," + dropObject.id;
  for (var i=0; i<dragObject.length; i++)
  {
    if ("search"==fromNodeId || this.tree.getViewDown())
      command += "," + dragObject[i][this.hierarchyColumnKey];
    else
      command += "," + fromNodeId;
    command += "," + dragObject[i][this.dataGrid.getKeyField()];
  }

  // This flag is used in onRecordModifyListener:
  this.dropInProgress = true;
  
  var event = this.parent.onRecordModify;
  this.postCommand(command, new REventListener(event.trigger, event));
}

RecordListViewTreeGrid.prototype.onDragStart = function(list, node, x, y)
{
  node.className = "dragItem";
  var table = document.createElement("table");
  node.appendChild(table);
  var tbody = document.createElement("tbody");
  table.appendChild(tbody);
  for (var i=0; i<list.length; i++)
  {
    var object = list[i];
    var name = object[this.dragField];
    var tr = document.createElement("tr");
    tbody.appendChild(tr);
    var td = document.createElement("td");
    tr.appendChild(td);
    td.innerHTML = name;
  }
}

RecordListViewTreeGrid.prototype.onSearchItemsLoad = function(jsObject)
{
  var searchNode = this.tree.getNode("search");
  if (!searchNode)
    searchNode = this.tree.appendNode("search", "Search Results", "treeSearchIcon");
  this.selectedTreeNode(searchNode);
}

RecordListViewTreeGrid.prototype.onSearchResetItemsLoad = function(jsObject)
{
  var node = null
  if (null != this.selectedNodeKey)
    node = this.tree.getNode(this.selectedNodeKey);
  if (null == node && null != this.defaultSelectedNodeKey)
    node = this.tree.getNode(this.defaultSelectedNodeKey);
  if (null == node)
    node = this.tree.getRootNode();
  this.selectedTreeNode(node);

  var searchNode = this.tree.getNode("search");
  if (searchNode)
    this.tree.removeNode(searchNode);
}
