% @since: 2014-01-15, @author: H Roumani, roumani@cse.yorku.ca %
classdef Tracker < c4e.InterfaceListener & c4e.ServoListener & c4e.RfidListener
   
   % The following attributes hold the object's state.
   % They are available to all methods in this class.
   properties
      servo;
      alarm;
      done;
      hpos;
      vpos;
      % add your attributes here
   end
    
   % The following functions exhibit the object's behavior
   methods
   
       function this = Tracker()  % Object Constructor, rename but do not modify
         engine = c4e.Engine(125, 100);
         engine.addPhidgetListener(this);     
         engine.start();
         this.servo = engine.getServoPhidget();
         this.alarm = engine;
         this.main();
         engine.stop();
       end   
      
      function main(this) % Called upon object creation
         global video;
        
         disp('Press ENTER to start ...'); pause;
         if (this.servo ~= [] && this.servo.isAttached())
            % Use the servo board, 
            disp('Servo Board Detected');
            this.done = 2;
            this.alarm.setTimerCallback();
            this.servo.setEngaged(0,  true);
            this.servo.setEngaged(1, true);
            this.hpos = 100;
            this.vpos = 100;
            this.servo.setPosition(0, this.hpos);
            this.servo.setPosition(1, this.vpos);
            while this.done ~= 0
                pause(1);
            end
         else
            disp('No servo board!');
         end
         disp('Press ENTER to terminate ...'); pause;
      end
          
      % ----------------------------------- These are event handlers
      function attached(this, event)
         %fprintf('Attach event at %d for phidget with serial number: %d\n', event.getWhen(), event.getId());
      end
      function detached(this, event)
         %fprintf('Detach event at %d for phidget with serial number: %d\n', event.getWhen(), event.getId());
      end
      function diChange(this, event)
         %fprintf('Digital input #%d became %g at %d\n', event.getId(), event.getValue(), event.getWhen());
      end
      function aiChange(this, event)
         %fprintf('Analog input #%d became %g at %d\n', event.getId(), event.getValue(), event.getWhen());
      end
      function doChange(this, event)
         %fprintf('Digital output #%d became %g at %d\n', event.getId(), event.getValue(), event.getWhen());
      end
      function servoPosition(this, event)
         %fprintf('Motor #%d position became %g at %d\n', event.getId(), event.getValue(), event.getWhen());
      end
      function servoVelocity(this, event)
         %fprintf('Motor #%d velocity became %g at %d\n', event.getId(), event.getValue(), event.getWhen());
      end
      function servoCurrent(this, event)
         %fprintf('Motor #%d current became %g at %d\n', event.getId(), event.getValue(), event.getWhen());
      end
      function rfidGain(this, event)
         %fprintf('RFID tag gain with protocol #%d and tag %s at %d\n', event.getId(), char(event.getTag()), event.getWhen());
      end
      function rfidLoss(this, event)
         %fprintf('RFID tag lost with protocol #%d and tag %s at %d\n', event.getId(), char(event.getTag()), event.getWhen());
      end
      function timerCallback(this)
         global video;
         fprintf('Alarm went off at: %s\n', datestr(now,'dd-mm-yyyy HH:MM:SS FFF'));
         if (this.done == 2)
           this.hpos = input('enter pan value (<= 0 to exit): ');
           if(this.hpos > 0)
             this.servo.setPosition(0, this.hpos);
           else
             this.done = 1;
           end
         elseif(this.done == 1)
           this.vpos = input('enter tilt value (<= 0 to exit): ');
           if(this.vpos > 0)
             this.servo.setPosition(1, this.vpos);
           else
             this.done = 0;
           end
         end

         for buffer = 1:10
            rgb = video.getFrameAsArray();
         end
         d = double(rgb);
         d = d./255;
         image(d);
         drawnow;
         if this.done ~= 0
           this.alarm.setTimerCallback();
         end
      end
   end
end
