/* L'objet Sprite_ctrl gère les déplacements 
  et intéractions avec les tuiles
  du Sprite_aspect associé */

function Sprite_ctrl(name,aspectobj){

  addobj(name,this);
  
  this.aspect=aspectobj;

  this.default_delay=0;
  this.default_rate=200;

  // l'appel suivant définit des propriétés importantes de l'objet Sprite_ctrl
  // voir prototype suivant
  this.reset_default();
  
  this.pending=null;
  
  this.lastd=3;
  this.dx=0;
  this.dy=0;
  this.fx=0;
  this.fy=0;
  this.nx=0;
  this.ny=0;
  this.keyact=[false,false,false,false];
  this.keystate=[false,false,false,false];
  this.keypending=[null,null,null,null];
  
  if (typeof(arguments[2])=="string")
    eval (arguments[2]);
}

Sprite_ctrl.prototype.reset_default=function(){
  this.delay=this.default_delay;
  this.rate=this.default_rate;
  this.repeat=true;
  this.viscosity=true;
  this.keycontrol=true;
}


Sprite_ctrl.prototype.key_action=function(d,way){
  if (way){
    this.keystate[d]=true;
    if (this.delay)
      this.keypending[d]=setTimeout(this.name+".steer("+d+")",this.delay);
    else
      this.steer(d);
  }
  else{
    this.keystate[d]=false;  
    if (this.keypending[d]){
      clearTimeout(this.keypending[d]);
      this.keypending[d]=null;
    }
    this.keyact[d]=false;
  }
}

Sprite_ctrl.prototype.steer=function(d){
  this.keypending[d]=null;
  // A ce niveau appeler une méthode (optionnelle) d'orientation du sprite (this.rotate(d))
  
  this.keyact[d]=true;
  if (!this.pending)
    this.shakeyourbody();
}

Sprite_ctrl.prototype.landing=function(){
  if (typeof(jumping)!="undefined") return;
  
  this.pending=null;
  this.aspect.set_xymap(this.nx,this.ny);
  this.reset_default();
  
  // gestion des hliens
  // désactiver pour modeauto
  if (typeof(hlinks)=="object"){
    var k=0;
    while (k<hlinks.length){
      if (    this.nx>=hlinks[k].x1 && this.nx<=hlinks[k].x2
           && this.ny>=hlinks[k].y1 && this.ny<=hlinks[k].y2  ){
        //alert("jump!");
        hlinkjump(hlinks[k]);
        return;    
      }
      k++;
    }
  }
    
  /*
  // trouver la tuile actuelle
  if (typeof(map)=="array" && this.nx>=0 && this.nx<wmap && this.ny>=0 && this.ny<hmap)
    this.loctile=tileset[map[this.ny][this.nx]];
  else
    this.loctile=false;*/
  
  // Appeler une méthode de la nouvelle tuile "landing" pour mods delay/rate/nohalt ...
  this.shakeyourbody();
}

Sprite_ctrl.prototype.shakeyourbody=function(){
  if (typeof(jumping)!="undefined") return;
  
  if (this.keycontrol){
    for (var d=0;d<4;d++){
      if (this.repeat)
        this.keyact[d]|=this.keystate[d];
      if (this.keyact[d]){
        this.fx+=DIRS[d].dx;
        this.fy+=DIRS[d].dy;
      }
      this.keyact[d]=false;
    }
  }
  
  if (this.viscosity)
    this.dx=this.dy=0;
  
  this.dx+=this.fx;
  this.dy+=this.fy;

  this.fx=this.fy=0;
  
  if (this.dx<-1) this.dx=-1;
  if (this.dx>1) this.dx=1;
  if (this.dy<-1) this.dy=-1;
  if (this.dy>1) this.dy=1;
  
  // On veut bouger ?
  if (this.dx || this.dy){
    this.nx=this.aspect.xmap+this.dx;
    this.ny=this.aspect.ymap+this.dy;
    if (this.canmove(this.nx,this.ny)){
      this.leaving(this.aspect.xmap,this.aspect.ymap);    

      // interrompre la fonction ici en cas de lien de bord :
      // links checked dans willmove
      
      this.willmove(this.nx,this.ny);
      
      // IE n'arrive pas à timer en dessous de 50
      // pour homogénéiser les comportements on fixe la limite
      if (this.rate<50) this.rate=50;
      this.animate(this.rate);
      this.pending=setTimeout(this.name+".landing()",this.rate);
    }
  }
}

// Pour l'instant se contente d'appeler la fonction de déplacement d'aspect
Sprite_ctrl.prototype.animate=function(tau){
  if (typeof(jumping)!="undefined") return;

  var sc=new Object();
  grid_layout(this.nx,this.ny,sc);
  
  // placement de tuile
  if (typeof(map)=="object" && this.nx>=0 && this.nx<wmap && this.ny>=0 && this.ny<hmap){
    //alert ("dolay");
    var loctile=tileset[map[this.ny][this.nx]];
    if (!loctile.sa) loctile.sa="m";
    if (typeof(this.layout)=="object"){
      var slay=false;
      if (loctile.sa=="b") slay=this.layout.bottom;
      else if (loctile.sa=="m") slay=this.layout.middle;
      else if (loctile.sa=="t") slay=this.layout.top;
      if (slay){
        sc.x=sc.x+(wtile>>1)+loctile.sx-slay.x;
        sc.y=sc.y+(htile>>1)+loctile.sy-slay.y;
        //alert(typeof(sc.z)+":"+sc.z+" "+typeof(loctile.sz)+":"+loctile.sz+" "+typeof(slay.z)+":"+slay.z);
        sc.z=sc.z+loctile.sz+parseInt(slay.z);
        //alert(typeof(sc.z)+":"+sc.z+" "+typeof(loctile.sz)+":"+loctile.sz+" "+typeof(slay.z)+":"+slay.z);
      }
    } 
  }
  
  this.aspect.set_xy(sc.x,sc.y);
  this.aspect.set_z(sc.z+4);
}

Sprite_ctrl.prototype.canmove=function(nx,ny){
  // réécrire pour vérifier préemptivement la possibilité 
  // de faire un déplacement torique (dans le cas links[0]==mapname)
  if (    (nx<wmap || nx<=wmap && links[1])
       && (nx>=0 || nx>=-1 && links[0])
       && (ny<hmap || ny<=hmap && links[3])
       && (ny>=0 || ny>=-1 && links[2])          ){
     
    // TODO vérifier légalité mouvment en appelant methode tuile "canmove"    
    if (nx<wmap && nx>=0 && ny<hmap && ny>=0){
      var loctile=tileset[map[this.ny][this.nx]];
      var locnow=tileset[map[this.aspect.ymap][this.aspect.xmap]];
      if (!nowall && (loctile.t=="mur" || loctile.t=="wall") && !(locnow.t=="mur" || locnow.t=="wall"))
        return 0;
    }
    return 1;
  }
  else
    return 0;
}

Sprite_ctrl.prototype.willmove=function(nx,ny){
  if (typeof(jumping)!="undefined") return;
  
  // si on atterit en dehors du cadre c'est qu'on a un lien et on va changer de carte
  var x=nx;
  var y=ny;
  if (x<0 || x>=wmap || y<0 || y>=hmap){
  
    // éliminer le cas des diagonales (vers bords gauche ou droit)
    if (x<0 && y<0) y=0;
    if (x>=wmap && y<0) y=0;
    if (x<0 && y>=hmap) y=hmap-1;
    if (x>=wmap && y>=hmap) y=hmap-1;
    
    if (x<0){
      this.nx=wmap-1;
      if (links[0]!=mapname) linkjump(links[0]);
    }
    else if (x>=wmap){
      this.nx=0;
      if (links[1]!=mapname) linkjump(links[1]);
    }
    else if (y<0){
      this.ny=hmap-1;
      if (links[2]!=mapname) linkjump(links[2]);
    }
    else if (y>=hmap){
      this.ny=0;
      if (links[3]!=mapname) linkjump(links[3]);
    }
    
  }

  // Appeler une méthode de tuile "willmove" pour custom éventuel (déplacement...)
}

Sprite_ctrl.prototype.leaving=function(x,y){
  // Appeler une méthode de tuile "leaving" pour custom éventuel (nettoyages/réafectations...)
}


function Sprite_aspect(name){

  addobj(name,this);
  
  this.elem=document.createElement("IMG");

  this.elem.className="sprite";
  this.elem.id="name";

  this.set_src("");
  this.set_xymap(0,0);
  this.set_xy(0,0);
  this.set_visibility("visible");
  this.layout=false;
  
  var hnd;
  if ( (hnd=document.getElementById("el_main_frame")) ) void 0;
  else hnd=document.body;
  hnd.appendChild(this.elem);
}

Sprite_aspect.prototype.destroy=function(){
  
  var hnd;
  if ( (hnd=document.getElementById("el_main_frame")) ) void 0;
  else hnd=document.body;
  hnd.removeChild(this.elem);

  removeobj(this);  
}

Sprite_aspect.prototype.set_src=function(src){
  this.elem.src=this.src=src;
}

Sprite_aspect.prototype.set_xymap=function(xmap,ymap){
  this.xmap=xmap;
  this.ymap=ymap;
  // TODO utiliser la fonction de placement externe
  // TOSHARE ??
  //this.set_xy(wtile*xmap,htile*ymap);
}

Sprite_aspect.prototype.set_xy=function(x,y){
  this.elem.style.left=this.x=x;
  this.elem.style.top=this.y=y;  
}

Sprite_aspect.prototype.set_z=function(z){
  this.elem.style.zIndex=this.z=z;
}

Sprite_aspect.prototype.set_visibility=function(v){
  this.visibility=this.elem.style.visibility=v;
}

