//class block manager
function blockMng(oSystem){
  //objects
  this.oSystem = oSystem;
  //properties
  this.oExtraBlocks = new Object();
  this.extraBlocksMaxZindex = 100;
  //methods
  this.loadBlock = loadBlock;
  this.loadExtraBlock = loadExtraBlock;
  this.parseBlockConfig = parseBlockConfig;
  this.removeBlock = removeBlock;
  this.closeExtraBlocks = closeExtraBlocks;
}

function loadBlock(blockName){
  if(!this[blockName]){
    //this.oSystem.oDebug.dm('loading block '+blockName);
    this.oSystem.oConnection.loadFile('./systems/'+this.oSystem.systemName+'/blocks/'+blockName+'/b_'+blockName+'.xml','oSystem.oBlockMng.parseBlockConfig',[blockName]);
  }else{
    this[blockName].manageBlock();
  }
}

function loadExtraBlock(blockName,bFloating,bAddClose){
  if(!this[blockName]){
    this.oSystem.oDebug.dm('loading extra block '+blockName);
    this.oSystem.oConnection.loadFile('./systems/'+this.oSystem.systemName+'/blocks/'+blockName+'/b_'+blockName+'.xml','oSystem.oBlockMng.parseBlockConfig',[blockName,true,bFloating,bAddClose]);
  }else{
    this[blockName].manageExtraBlock(bFloating,bAddClose);
  }
}

function parseBlockConfig(xCode,blockName,bExtraBlock,bFloating,bAddClose){
  bAddClose = bAddClose == 'true' ? Boolean(true) : Boolean(false); 
  //this.oSystem.oDebug.dm('parsing block '+blockName+' config file');
  var oXml = this.oSystem.oConnection.generateXDoc('xml',xCode);
  try{
    var oNode = oXml.getElementsByTagName('content_type')[0];
    var contentType = this.oSystem.oConnection.getNodeValue(oNode);
  }catch(err){
    this.oSystem.oDebug.de('content type for block \''+blockName+'\' not defined');
    return false;
  }
  
  try{
    var oNode = oXml.getElementsByTagName('behaviour')[0];
    var behaviour = this.oSystem.oConnection.getNodeValue(oNode);
  }catch(err){
    this.oSystem.oDebug.de('behaviour for block \''+blockName+'\' not defined');
    return false;
  }
  var bJsReload = this.oSystem.oConnection.getNodeAttribute(oNode,'js_reload');
  
  if(bJsReload){
    try{
      if(typeof(oLocal) == 'undefined') 
      throw 'Err1';
      if(typeof(oLocal.jsUpdate) == 'undefined') 
      throw 'Err2';
    }catch(err){
      if(err == 'Err1') this.oSystem.oDebug.de('oLocal not defined, could not load block \''+blockName+'\'');
      if(err == 'Err2') this.oSystem.oDebug.de('oLocal.jsUpdate not defined, could not load block \''+blockName+'\'');
      return false;
    }
  }
  
  try{
    oNode = oXml.getElementsByTagName('source')[0];
    var source = this.oSystem.oConnection.getNodeValue(oNode);
  }catch(err){
    this.oSystem.oDebug.de('source for block \''+blockName+'\' not defined');
    return false;
  }
  if(source == 'dynamic'){
    if(behaviour == 'fixed'){
      try{
        oNode = oXml.getElementsByTagName('source_class')[0];
        var sourceClass = this.oSystem.oConnection.getNodeValue(oNode);
      }catch(err){
        this.oSystem.oDebug.de('source class for dynamic fixed block \''+blockName+'\' not defined');
        return false;
      }
      try{
        oNode = oXml.getElementsByTagName('source_method')[0];
        var sourceMethod = this.oSystem.oConnection.getNodeValue(oNode);
      }catch(err){
        this.oSystem.oDebug.de('source method for dynamic fixed block \''+blockName+'\' not defined');
        return false;
      }
    }else if(behaviour == 'source_reload'){
      if(!this.oSystem.oPage.oBlocksParameters[blockName].sourceClass) this.oSystem.oDebug.de('source class for dynamic source_reload block \''+blockName+'\' not defined');
      if(!this.oSystem.oPage.oBlocksParameters[blockName].sourceMethod) this.oSystem.oDebug.de('source method for dynamic source_reload block \''+blockName+'\' not defined');
    }
  }else{
    var sourceClass;
    var sourceMethod;
  }
  var aCss = oXml.getElementsByTagName('css');
  var nCss;
  var cssName;
  for(i=0;i<aCss.length;i++){
    nCss = aCss.item(i);
    cssName = this.oSystem.oConnection.getNodeValue(nCss);
    this.oSystem.oHtmlMng.loadCss('./systems/'+this.oSystem.systemName+'/blocks/'+blockName+'/'+cssName+'.css');
  }

  this[blockName] = new block(this.oSystem,blockName,contentType,source,sourceClass,sourceMethod,behaviour,bJsReload);
  if(bExtraBlock) this[blockName].manageExtraBlock(bFloating,bAddClose);
  else this[blockName].manageBlock();
}

function removeBlock(blockName){
  this[blockName].displaying = false;
  this[blockName].oContainer = false;
}

function closeExtraBlocks(){
  for(i in this.oExtraBlocks){
    this[i].closeExtra();
  }
}

//class block
function block(oSystem,name,contentType,source,sourceClass,sourceMethod,behaviour,bJsReload){
  //objects
  this.oSystem = oSystem;
  this.oXml;
  this.oXsl;
  //properties
  this.name = name;
  this.contentType = contentType;
  this.source = source;
  this.sourceClass = sourceClass;
  this.sourceMethod = sourceMethod;
  this.behaviour = behaviour;
  this.bJsReload = bJsReload;
  this.oContainer = false;
  //methods
  this.manageBlock = manageBlock;
  this.manageExtraBlock = manageExtraBlock;
  this.getBlock = getBlock;
  this.loadPageParameters = loadPageParameters;
  this.manageXml = manageXml;
  this.manageXsl = manageXsl;
  this.doTransform = doTransform;
  this.displayBlock = displayBlock;
  this.displayExtraBlock = displayExtraBlock;
  this.close = close;
  this.closeExtra = closeExtra;
  this.refreshJsBlock = refreshJsBlock;
  this.sort = sort;
}

function manageXml(xCode,bExtraBlock){
  var oXml = this.oSystem.oConnection.generateXDoc('xml',xCode);
  this.oXml = oXml;
  if(!this.oXsl){
    //this.oSystem.oDebug.dm('getting xsl for block '+this.name);
    this.oSystem.oConnection.loadFile('./systems/'+this.oSystem.systemName+'/blocks/'+this.name+'/'+this.name+'.xsl', 'oSystem.oBlockMng.'+this.name+'.manageXsl',[bExtraBlock]);
  }else{
    this.doTransform(bExtraBlock);
  }
}

function manageXsl(xCode,bExtraBlock){
  var oXsl = this.oSystem.oConnection.generateXDoc('xsl',xCode);
  this.oXsl = oXsl;
  this.doTransform(bExtraBlock);
}

function doTransform(bExtraBlock,sortFieldName,sortDataType,sortOrder){
  sortFieldName = sortFieldName ? sortFieldName : false;
  var htmlCode = this.oSystem.oHtmlMng.xslTransform(this.name,sortFieldName,sortDataType,sortOrder);
  //delete this.oXml;
  this.displayBlock(htmlCode,bExtraBlock);
}

function manageBlock(){
  //this.oSystem.oDebug.dm('managing block '+this.name);
  if(!this.displaying){
    this.oContainer = this.oSystem.oHtmlMng.createBlockContainer(this.name);
    this.getBlock(false);
  }else{
    if(this.behaviour == 'source_reload'){
      this.getBlock(false);
    }else if(this.bJsReload && this.oSystem.oPage.bNewPage){
      this.refreshJsBlock();
    }
  }
}

function manageExtraBlock(bFloating,bAddClose){
  this.oSystem.oDebug.dm('managing extra block '+this.name+' ('+bFloating+')');
  if(!this.displaying){
    this.oContainer = this.oSystem.oHtmlMng.createExtraBlockContainer(this.name,bFloating,bAddClose);
    this.getBlock(true);
  }else if(bFloating){
    this.oSystem.oHtmlMng.bringExtraBlockToFront(this.name);
  }
}

function getBlock(bExtraBlock){
  //this.oSystem.oDebug.dm('getting block source for block '+this.name+' ('+bExtraBlock+')');
  var loadMethod = (this.contentType == 'html') ? 'displayBlock' : 'manageXml';
  var fileToLoad;
  if(this.source == 'static'){
    if(this.behaviour == 'fixed'){
      fileToLoad = './systems/'+this.oSystem.systemName+'/blocks/'+this.name+'/'+this.name+'.'+this.contentType;
    }else if(this.behaviour == 'source_reload'){
      fileToLoad = './systems/'+this.oSystem.systemName+'/blocks/'+this.name+'/'+this.oSystem.oPage.name+'.'+this.contentType;
    }
  }else if(this.source == 'dynamic'){
    if(this.behaviour == 'fixed'){
       fileToLoad = './_libs/php/get_data.php?system='+this.oSystem.systemName+'&sourceClass='+this.sourceClass+'&sourceMethod='+this.sourceMethod;
    }else if(this.behaviour == 'source_reload'){
      fileToLoad = './_libs/php/get_data.php?'+this.loadPageParameters();
    }
  }  
  this.oSystem.oConnection.loadFile(fileToLoad, 'oSystem.oBlockMng.'+this.name+'.'+loadMethod,[bExtraBlock]);
}

function loadPageParameters(){
  var sPars = 'system='+this.oSystem.systemName;
  for(i in this.oSystem.oPage.oBlocksParameters[this.name]){
    //this.oSystem.oDebug.dm('parameter for block '+this.name+': '+i+' = '+this.oSystem.oPage.oBlocksParameters[this.name][i]);
    sPars += '&'+i+'='+this.oSystem.oPage.oBlocksParameters[this.name][i];
  }
  return sPars;
}

function displayBlock(htmlCode,bExtraBlock){
  if(bExtraBlock == 'true') this.displayExtraBlock(htmlCode);
  else{
    //this.oSystem.oDebug.dm('displaying block '+this.name);
    this.displaying = true;
    this.oContainer.innerHTML = htmlCode;
    if(this.bJsReload) this.refreshJsBlock();
  }
}

function displayExtraBlock(htmlCode){
  this.oSystem.oDebug.dm('displaying extra block '+this.name);
  this.oSystem.oBlockMng.extraBlocksMaxZindex++;
  this.displaying = true;
  this.oSystem.oBlockMng.oExtraBlocks[this.name] = true;
  this.oContainer.innerHTML += htmlCode;
  if(this.bJsReload) this.refreshJsBlock();
}

function close(bFloating){
  this.oSystem.oDebug.dm('closing block '+this.name);
  this.displaying = false;
  delete this.oContainer;
  this.oSystem.oHtmlMng.deleteBlock(this.name,bFloating);
}
function closeExtra(){
  this.close(true);
  delete this.oSystem.oBlockMng.oExtraBlocks[this.name];
}

function refreshJsBlock(){
  //this.oSystem.oDebug.dm('js refreshing block '+this.name+' for page '+this.oSystem.oPage.name);
  oLocal.jsUpdate(this.name);
}

function sort(fieldName,sortDataType,sortOrder,bExtraBlock){
  this.oSystem.oDebug.dm('sorting block '+this.name+' by field '+fieldName);
  this.doTransform(bExtraBlock,fieldName,sortDataType,sortOrder);
}
