Require Class/basicSurface

basicSurface Subclass basicSurfaceOfRevolution {
  Var F C D
  ClassVar {param t} function rotate-axes {rotate-point {0 0}}
  ClassVar "domain {{-pi pi 24} {[lindex [basicSurface get domain] 0]}}"

  Method Compute {} {
    Vars F C D domain uv param function rotate-axes rotate-point
    Self InheritVars axes point

    Self Color Init
    upvar [lindex $uv 0] u
    upvar [lindex $uv 1] v
    upvar _X _X
    set F {}; set C {}; set D {}

    if {[llength ${rotate-axes}] != 2} \
      {Error "Rotation must be specified by the plane of two axes"}
    set i 0
    foreach a $axes {
      if {$a == [lindex ${rotate-axes} 0]} {set Ax $i}
      if {$a == [lindex ${rotate-axes} 1]} {set Ay $i}
      incr i
    }
    if ![info exists Ax] {Error "Unknown axis '[lindex ${rotate-axes} 0]'"}
    if ![info exists Ay] {Error "Unknown axis '[lindex ${rotate-axes} 1]'"}
    if {$Ax == $Ay} {Error "Plane of rotation must have two different axes"}
    set P [uplevel [list _expr(Math) ${rotate-point}]]
    if {[llength $P] != 2} {Error "Point must be in the plane of rotation"}
    _expr(Let) {_X(0) _X(1)} $P
    set x0 $_X(0); set y0 $_X(1); set _X(0) 0; set _X(1) 0
    upvar _X($Ax) x; upvar _X($Ay) y

    foreach UV [Self GetDomainList [uplevel [list subst $domain]]] {
      Self GetDomain $UV
      lappend D [lreplace $UV 0 1 [list $um $uM $un] [list $vm $vM $vn]]
      set colorfn [lindex $UV 3]
      set _F {}; set _C {}
      for {set i 0; set u $um} {$i <= $un} {incr i; set u [expr $i*$ud+$um]} \
        {set cos($i) [expr cos($u)]; set sin($i) [expr sin($u)]}
      for {set j 0; set v $vm} {$j <= $vn} {incr j; set v [expr $j*$vd+$vm]} {
        set x 0; set y 0
        _script(Run) $function
	set xx [expr $x-$x0]; set yy [expr $y-$y0]
        for {set i 0; set u $um} {$i <= $un} {incr i;set u [expr $i*$ud+$um]} {
          set x [expr $xx*$cos($i) - $yy*$sin($i) + $x0]
          set y [expr $xx*$sin($i) + $yy*$cos($i) + $y0]
	  lappend _F [uplevel $point]
	  lappend _C [eval [list $ColorFN $colorfn]]
	}
      }
      lappend F $_F
      lappend C $_C
    }
    Self NormalizeColors
  }

  Method SetUV {} {
    Vars param uv
    if {$param == "theta"} {set t "t"} else {set t "theta"}
    set uv [list $t $param]
  }

  Method Create {name {data ""}} {
    set name [Parent Create $name $data]
    if {$data == ""} {$name Data set wrapU 1}
    return $name
  }
}
