Require Class/basicCurve
Require Class/basicSurface

basicCurve Subclass basicCurveFromSurface {
  Var P NUV function f-setup "param {[basicCurve get param]}"
  ClassVar {linkable-types basicSurface}
  ClassVar f-xy {frame 0} cfunction

  Method SetValues {} {
    Vars function f-setup param frame f-xy cfunction
    set object [Self Reference Object]
    set point [Self Inherit point]
    set P [var P]

    if {$frame && [$object getDimension] != 3} \
      {Error "Frame-based actions only work when '$object' is in 3 dimensions"}

    set f-setup [list "uplevel {upvar \#0 $P $P}"]

    if {$frame} {
      set NUV [var NUV]; lappend f-setup "uplevel {upvar \#0 $NUV $NUV}"
      set function [join [list \
        ${f-xy} \
        {set _u $_X(0); set _v $_X(1)} \
        "set $NUV \[Transpose \[join \[$object NUV \$_u \$_v\] { }\]\]" \
        "set $P \[$object F \$_u \$_v\]" \
        {foreach _i [array names _X] {set _X($_i) 0}} \
        ${cfunction} \
        "set _P \[+ \${$P} \[* \${$NUV} \[$point\]\]\]" \
        {foreach _i [array names _X] {set _X($_i) [lindex $_P $_i]}} \
      ] \n]
    } else {
      set function [join [list \
        ${f-xy} \
        "set $P \[$object F \$_X(0) \$_X(1)\]" \
        {foreach _i [array names _X] {set _X($_i) 0}} \
        ${cfunction} \
        "set _P \[+ \${$P} \[$point\]\]" \
        {foreach _i [array names _X] {set _X($_i) [lindex $_P $_i]}} \
      ] \n]
    }

    set f-setup [join ${f-setup} \n]
  }

  Method Inherit {var} {Self InheritReference $var}
}
