// PheliX <phelix.truba@gmail.com> http://savs.sytes.net
// http://www.metaleks.lv

// requires sys.js

// + RPC + =====================================================================
function requestFunc(){
 var tryThese = [
  function(){ return new XMLHttpRequest();                      },
  function(){ return new ActiveXObject( 'Microsoft.XMLHTTP' );  },
  function(){ return new ActiveXObject( 'Msxml2.XMLHTTP' );     },
  function(){ return new ActiveXObject( 'Msxml2.XMLHTTP.4.0' ); }
 ];
 for( var i = 0, len = tryThese.length; i < len; ++i ){
  var func = tryThese[ i ];
  try {
   var x = func();
   if( typeof x != 'undefined' ){
    return func;
   }
  }catch( e ){}
 }
 return doNothing;
}
var newXMLHttpRequest = requestFunc();

function rpc( uri ){
 this.uri  = uri;
 this.proc = new l();
}
rpc.prototype.send = function( func, param, respFunc, respFuncParams ){
 if( newXMLHttpRequest !== doNothing ){
  var respFuncReq       = respFunc;
  var respFuncParamsReq = respFuncParams;
  var req               = newXMLHttpRequest();
  var xml               = ob2sdxml( func, param );

  req.open( 'POST', this.uri, true );
  req.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );

  var thisOb             = this;
  req.onreadystatechange = function(){
   if( responseReady( req ) ){
    var resp = rpcCatchError( rpc2ob( req ) );
    respFuncReq( resp, respFuncParamsReq );
    respFuncReq = doNothing;                // IE 5.0
    thisOb.proc.rm( req );
   }
  }

  this.proc.add( req );
  req.send( 'SDXML-RPC=' + xml.toUrl() );
  return true;
 }else{
  //alert( 'XMLHttpRequest not supported' );
  return false;
 }
}
var RPC = new rpc( '/sys/rpc.php' );

function responseReady( req ){
 if( req.readyState == 4 ){
  if( req.status == 200 ){
   return true;
  }else{
   alert( 'Error while retrieving XML data:\n' + 'status:' + req.status + '\nresponse:\n' + req.statusText );
   return false;
  }
 }
 return false;
}

function rpcCatchError( resp ){
 if( resp.v( 'error' ) ){
  if( resp.v( 'error' ).v( 'msg' ) ){
   //alert( resp.v( 'error' ).v( 'msg' ) );
  }
  return false;
 }else{
  return resp.v( 'ok' );
 }
}
// - RPC - =====================================================================

// + SDXML2Ob + ================================================================
function XMLfirstChildVal( val ){
 var node;
 for( var it = 0; node = val.childNodes[ it ]; ++it ){
  if( node.nodeType == 3 ) return node;
 }
 return false;
}

function ob2sdxml( func, param ){
 return '<rpc method="' + func + '">' + param.toSdxml() + '</rpc>';
}

function rpc2ob( rpc ){
 if( rpc.responseXML.firstChild.nodeName == 'xml' ){  // IE
  rpc2ob = function( rpc ){
   return dom2ob( rpc.responseXML.firstChild.nextSibling );
  }
  return dom2ob( rpc.responseXML.firstChild.nextSibling );
 }
 rpc2ob = function( rpc ){
  return dom2ob( rpc.responseXML.firstChild );
 }
 return dom2ob( rpc.responseXML.firstChild );
}

function dom2txt( dom ){
 var txt = '';
 var child;
 if( dom.childNodes ){
  var it = 0;
  while( child = dom.childNodes[ it++ ] ){
   txt += child.nodeType + ':' + child.nodeName + ':' + child.nodeValue + ' ';
   if( child.attributes ){
    var jt = 0;
    while( att = child.attributes[ jt++ ] ){
     txt += att.nodeType + ':' + att.nodeName + ':' + att.nodeValue + ' ';
    }
   }
   txt += '\n';
   txt += dom2txt( child );
  }
 }
 return txt;
}

function dom2ob( nod ){
 var va;
 if( nod.nodeType == 1 ){
  switch( nod.nodeName ){
   case 's':
   case 'e':
    if( va = XMLfirstChildVal( nod ) ){
     return new String( va.nodeValue );
    }
    return '';
   case 'n':
   case 'f':
    if( va = XMLfirstChildVal( nod ) ){
     return new Number( va.nodeValue );
    }
    return 0;
   case 'b':
    if( va = XMLfirstChildVal( nod ) ){
     return ( va.nodeValue == true )? true: false;
    }
    return false;
   case 'l':
    var tmpL = new l();
    var item;
    var len = nod.childNodes.length;
    for( var it = 0; it < len; ++it ){
     var item = nod.childNodes[ it ];
     if( item.nodeType == 1 ){
      tmpL.add( dom2ob( item ) );
     }
    }
    return tmpL;
   case 'i':
    var tmpI = new i();
    var item;
    var len = nod.childNodes.length;
    for( var it = 0; it < len; ++it ){
     var item = nod.childNodes[ it ];
     if( item.nodeType == 1 ){
      tmpI.v( dom2key( item ), dom2ob( item ) );
     }
    }
    return tmpI;
  }
 }
 return null;
}

function dom2key( nod ){
 var attr = nod.getAttribute( 'k' );
 if( attr ){
  return attr;
 }
 return false;
}
// - SDXML2Ob - ================================================================

