import flash.display3D.Context3D;

import flash.xml.XML;
import flash.xml.XMLList;
import flash.xml.XMLParser;

class WMAtom extends WMObjBase {
  public var pos( __getPos, __setPos ):Point3D;
  public var opos( __getOrgPos, __setOrgPos ):Point3D;

  public function new( ?r:Float = 1.0,
                       ?c0:Int = 0x00FF00,
                       ?c1:Int = 0x00FF00,
                       ?a:Float = 1.0,
                       ?o:Float = 0.0,
                       ?q:Int = 3,
                       ?ag:Float = 0.35,
                       ?d:Float = 0.7,
                       ?sp:Float = 0.8,
                       ?gl:Float = 20.0,
                       ?sh:String = "Phong" ) {
    super( r, c0, c1, a, o, q, ag, d, sp, gl, sh );
    pos = null;
    opos = null;
    _polygon = null;
  }

  public override function clear( ?def:WMDefaults = null ):Void {
    if ( def != null ) {
      copyFrom( def.Atom );
    } else {
      radius = 1.0;
      color0 = 0x00FF00;
      color1 = 0x00FF00;
      alpha = 1.0;
      offset = 0.0;
      quality = 3;
      ambient = 0.35;
      diffuse = 0.7;
      specular = 0.8;
      gloss = 20.0;
      shader = "Phong";
    }
    pos = null;
    opos = null;
    _polygon = null;
  }

  public override function loadFromXml( x:Xml,
                                        ?def:WMDefaults = null ):Void {
    super.loadFromXml( x, def );
    if ( !x.exists( "pos" ) ) {
      trace( "pos attribute is required for an ATOM" );
      return;
    }
    pos = Point3D.fromString( x.get( "pos" ) );
    opos = pos;
  }

  public function gen( c:Context3D ):Void {
    _polygon = new Sphere3D( WMBase.getRelative( radius ), quality );
    _polygon.translate( pos.x, pos.y, pos.z );
    _polygon.allocate( c, shader, color0, alpha );
  }

  public function __getPos():Point3D { return( pos ); }
  public function __getOrgPos():Point3D { return( opos ); }
  public function __setPos( p:Point3D ):Point3D {
    if ( p != null ) {
      pos = p.clone();
    }
    return( pos );
  }
  public function __setOrgPos( p:Point3D ):Point3D {
    if ( p != null ) opos = p.clone();
    return( opos );
  }

  public function num():Int { return(1); }
  public function sumPos():Point3D { return( pos ); }
  public function translate( p:Point3D ):Void { pos.add( p ); }
  public function absmax():Point3D {
    var ret:Point3D = new Point3D( 0, 0, 0 );
    ret.x = Math.abs( pos.x );
    ret.y = Math.abs( pos.y );
    ret.z = Math.abs( pos.z );
    return( ret );
  }
  public function scaleCoord( scale:Float ):Void {
    pos.multiply( scale );
  }
}
