/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.graphics',
  name:  'Turntable',

  extends: 'foam.graphics.CView',

  properties: [
    {
      model_: 'IntProperty',
      name:  'r',
      label: 'Radius',
      defaultValue: 150
    },
    {
      name:  'width',
      defaultValue: 350
    },
    {
      name:  'height',
      defaultValue: 350
    },
    {
      name:  'x',
      defaultValue: 10
    },
    {
      name:  'y',
      defaultValue: 10
    },
    {
      model_: 'FloatProperty',
      name:  'rpm',
      label: 'RPM',
      help:  'Rotations Per Minute. Standard values: 33, 45, and 78.',
      defaultValue: 33
    },
    {
      name:  'internalTime',
      postSet: function(_, newValue) { if ( this.active ) this.time = newValue; }
    },
    {
      name:  'time',
      preSet: function(_, newValue) {
        if ( this.view ) this.view.paint();

        // When active, don't accept external changes to time.  Override by firing event back to
        // internalTime value.
        if ( this.active ) {
          if ( newValue != this.internalTime ) this.propertyChange('time', newValue, this.internalTime);
          return this.internalTime;
        }

        return newValue;
      }
    }
  ],

  listeners: {
    mouseDown: function(evt) {
      this.active = true;
      this.internalTime = this.time;
      this.touchX = evt.offsetX - this.r - this.x;
      this.touchY = evt.offsetY - this.r - this.y;
      this.theta = this.angle(this.touchX, this.touchY);
    },
    mouseUp: function(evt) {
      this.active = false;
    },
    mouseMove: function(evt) {
      if ( ! this.active ) return;

      this.touchX = evt.offsetX - this.r - this.x;
      this.touchY = evt.offsetY - this.r - this.y;

      var prevA = this.theta;
      this.theta = this.angle(this.touchX, this.touchY);
      var d = this.theta - prevA;
      if ( d > Math.PI*1.5 ) d -= Math.PI*2;
      if ( d < -Math.PI*1.5 ) d += Math.PI*2;
      if ( d == 0 ) return;

      var dTime = d/(Math.PI*2)*36000/this.rpm;
      this.time = this.internalTime = this.internalTime + dTime;
    }
  },

  methods: {
    initCView: function() {
      this.SUPER();

      this.r = this.r;

      this.$.onmousedown = this.mouseDown;
      this.$.onmouseup   = this.mouseUp;
      this.$.onmousemove = this.mouseMove;
    },

    angle: function(x,y) {
      return Math.atan2(y-this.y, x-this.x);
    },

    paintSelf: function() {
      var c = this.canvas;
      c.save();
      c.translate(this.r, this.r);
      c.font = "48pt Arial";

      c.lineWidth = 12;
      c.globalAlpha = 0.25;

      c.beginPath();
      c.fillStyle = 'black';
      c.arc(this.x,this.y,this.r-12,0,Math.PI*2,true);
      c.stroke();

      c.beginPath();
      c.fillStyle = 'black';
      c.arc(this.x,this.y,5+(this.r-12)/2,0,Math.PI*2,true);
      c.stroke();

      var r4 = (this.r-10)/4;
      var p = -0.25*this.rpm*this.time/36000*Math.PI*2;
      c.beginPath();
      c.strokeStyle = 'black';
      c.arc(this.x+(10+r4)*Math.sin(p),this.y+(10+r4)*Math.cos(p),r4,0,Math.PI*2,true);
      c.stroke();

      var p = -this.rpm*this.time/36000*Math.PI*2;
      c.beginPath();
      c.fillStyle = 'black';
      c.arc(this.x+(10+3*r4)*Math.sin(p),this.y+(10+3*r4)*Math.cos(p),r4,0,Math.PI*2,true);
      c.stroke();

      /*
      c.save();
      c.translate(this.x,this.y);
      c.rotate(this.rpm*this.time/36000*Math.PI*2);
      c.translate(-this.x,-this.y);
      c.fillStyle = '#999';
      c.fillText("FOAM", this.x-92, this.y+25);
      c.restore();
      */

      c.beginPath();
      c.fillStyle = 'black';
      c.arc(this.x,this.y,8,0,Math.PI*2,true);
      c.stroke();

      if ( this.active ) {
        c.lineWidth = 15;
        c.strokeStyle = 'blue';
        c.beginPath();
        c.arc(this.touchX,this.touchY,r4,0,Math.PI*2,true);
        c.stroke();

        c.lineWidth = 3;
        var dx = this.touchX - this.x;
        var dy = this.touchY - this.y;
        var r  = Math.sqrt(dx*dx + dy*dy);
        var a = Math.atan2(dy, dx);

        r = Math.round(r / 20) * 20;
        c.beginPath();
        c.strokeStyle = 'blue';
        c.arc(this.x,this.y,r,a+Math.PI*0.8,a-Math.PI*0.8,true);
        c.stroke();
      }

      c.restore();
    }
  }
});

@@ -1850,32 +1850,31 @@
 rs: 
-%7B%0A    mouseDown: functio
+%5B%0A    function mouseDow
 n(ev
@@ -2115,25 +2115,16 @@
     
-mouseUp: 
 function
 (evt
@@ -2111,32 +2111,40 @@
  %7D,%0A    function
+ mouseUp
 (evt) %7B%0A      th
@@ -2173,16 +2173,25 @@
  %7D,%0A    
+function 
 mouseMov
@@ -2191,26 +2191,16 @@
 ouseMove
-: function
 (evt) %7B%0A
@@ -2700,17 +2700,17 @@
     %7D%0A  
-%7D
+%5D
 ,%0A%0A  met

Fix Turntable listeners.