// VideoMsgProducer
//   record
//   live
//   send (i.e., upload)
	
function VideoMsgProducer()
{
  var _this = this;

  this.eventManager = EventManager;
  this.eventManager();
  
  var previewActive = false;
  var autoPreview = false;

  var captureInProgress = false;
  var captureCancelled = false;
  var captureTicks = 0;
  var captureTicksMax = 120;

  var encodeInProgress = false;
  var encodeCancelled = false;
  var encodeTicks = 0;
  var encodeTicksMax = captureTicksMax * 2;

  var uploadInProgress = false;
  var uploadCancelled = false;
  var uploadTicks = 0;
  
  // CAPTURE

  this.startCapture = function()
  {
    if (captureInProgress)
    {
      this.reportEvent('error_alreadyCapturing','Already recording');
      return false;
    }
    this.reportEvent('info_captureStarted','Capture started');
    captureInProgress = true;
    captureCancelled = false;    
    captureTicks = 0;

    if (!previewActive)
    {
      autoPreview = true;
      this.startPreview();
    }
    CameraCapture.startCapture();
    setTimeout(_this.monitorCapture._bind(_this),1000);
    return true;
  }

  this.monitorCapture = function()
  {
    if (captureInProgress)
    {
      if (++captureTicks > captureTicksMax)
      {
	this.stopCapture();
	this.captureTerminationEvent('info_maxCaptureTimeExceeded','Max capture time exceeded');
      }
      else
      {
	setStatusClockEnabled(false);
	var statusText = ' recording... '+captureTicks;
	windowStatus(statusText);
	this.fireEventDescriptor(this.buildEventDescriptor('info_vmpStatus',statusText));
	setTimeout(_this.monitorCapture._bind(_this),1000);
      }
    }
  }

  this.stopCapture = function()
  {
    //directorTrace('VideoMsgProducer.stopCapture');
    if (captureInProgress)
    {
      if (previewActive && autoPreview)
      {
//	this.stopPreview();
      }
      CameraCapture.stopCapture();
      captureInProgress = false;
      var statusText = ' recording stopped at... '+captureTicks;
      windowStatus(statusText);
      this.fireEventDescriptor(this.buildEventDescriptor('info_vmpStatus',statusText));

      this.captureTerminationEvent('info_captureStopped','Capture stopped');
      if (!captureCancelled)
      {
	setTimeout(_this.encode._bind(_this),1000);
      }
    }
  }
  
  this.startPreview = function()
  {
    previewActive = true;
    CameraCapture.startPreview();
    this.reportEvent('info_previewStarted','Preview started');
  }

  this.stopPreview = function()
  {
    //directorTrace('VideoMsgProducer.stopPreview');
    previewActive = false;
    autoPreview = false;
    CameraCapture.stopPreview();
    this.reportEvent('info_previewStopped','Preview stopped');
  }

  this.cancelCapture = function()
  {
    captureCancelled = true;
    this.captureTerminationEvent('info_captureCancelled','Capture cancelled');
    this.stopCapture();
  }

  this.captureTerminationEvent = function(event,eventDescriptor)
  {
    this.reportEvent(event,eventDescriptor);
    captureInProgress = false;
  }

  this.reportEvent = function(event,eventDescriptor)
  {
    if (false)
    {
      directorTrace('VideoMsgProducer.reportEvent' +
		    '\n event: ' + event +
		    '\n eventDescriptor: ' + eventDescriptor);
    }
    this.notifyDependents(event,eventDescriptor);
  }

  

  // ENCODE

  this.encode = function()
  {
    var status = null;
    this.anonProject = new Project();
    if (this.anonProject.create() === null)
    {
      this.encodeTerminationEvent('error_unableToCreateProject','Unable to create project');
      return;
    }

    try {status = this.anonProject.addClip(CameraCapture.getCapturePath());}
    catch (e)
    {
      this.encodeTerminationEvent('error_addClipException','Add clip exception:' + e.message);
      alert('VideoMsgProducer.encode EXCEPTION: ' + e.message);
      alert(e.message);
      alert(CameraCapture.getCapturePath());
      return;
    }

    if (status === null)
    {      
      this.encodeTerminationEvent('error_unableToAddClip','Unable to add clip');
      alert(CameraCapture.getCapturePath());
      return;
    }

    this.configureEncode(this.anonProject);

    if (!this.anonProject.encode())
    {
      this.encodeTerminationEvent('error_unableToEncodeClip','Unable to encode clip');
      alert(CameraCapture.getCapturePath());
      return;
    }

    encodeInProgress = true;
    encodeCancelled = false;
    encodeTicks = 0;
    setTimeout(_this.monitorEncode._bind(_this),1000);
  }

  this.monitorEncode = function()
  {
    if (encodeInProgress)
    {
      if(this.anonProject.isEncoding())
      {
	encodeTicks++;
	setStatusClockEnabled(false);
	var statusText = ' encoding... '+ encodeTicks;
	windowStatus(statusText);
	this.fireEventDescriptor(this.buildEventDescriptor('info_vmpStatus',statusText));
	setTimeout(_this.monitorEncode._bind(_this),1000);
      }
      else
      {
	encodeInProgress = false;
	this.encodeTerminationEvent('info_encodeComplete','Encode complete');
	var statusText = 'encode complete... '+encodeTicks;
	windowStatus(statusText);
	this.fireEventDescriptor(this.buildEventDescriptor('info_vmpStatus',statusText));
	setTimeout(_this.upload._bind(_this),1000);
      }
    }
  }

  this.cancelEncode = function()
  {
    encodeInProgress = false;
  }

  this.encodeTerminationEvent = function(event,eventDescriptor)
  {
    this.reportEvent(event,eventDescriptor);
    encodeInProgress = false;
  }


  // UPLOAD

  this.upload = function()
  {
    var name = (msgSubject != null) ? msgSubject : 'message';
    var status = this.anonProject.uploadAs(name);
    if (!status)
    {
      this.uploadTerminationEvent('error_unableToUploadClip','Unable to upload clip');
    }
    else
    {
      uploadCancelled = false;
      uploadTicks = 0;
      uploadInProgress = true;
      setTimeout(_this.monitorUpload._bind(_this),1000);
    }
  }

  this.monitorUpload = function()
  {
    if (uploadInProgress)
    {
      if(this.anonProject.isUploading())
      {
	uploadTicks++;
	setStatusClockEnabled(false);
	var statusText = ' uploading... '+ uploadTicks;
	windowStatus(statusText);
	this.fireEventDescriptor(this.buildEventDescriptor('info_vmpStatus',statusText));
	setTimeout(_this.monitorUpload._bind(_this),1000);
      }
      else
      {
	uploadInProgress = false;
	this.uploadTerminationEvent('info_uploadComplete',this.buildEventDescriptor('info_uploadComplete',VideoMsgProducer.lastMsgName));
	this.startPreview();
	//var statusText = '[' + uploadTicks + ']UPLOAD COMPLETE';
	//windowStatus(statusText);
	//this.fireEventDescriptor(this.buildEventDescriptor('info_vmpStatus',statusText));
      }
    }
  }

  this.cancelUpload = function()
  {
    uploadInProgress = false;
  }

  this.uploadTerminationEvent = function(event,eventDescriptor)
  {
    this.reportEvent(event,eventDescriptor);
    uploadInProgress = false;
  }




  this.stopAll = function()
  {
    this.stopCapture();
    this.stopPreview();
  }

  var msgSubject = null;
  this.recordAs = function(subject) // USER API
  {
    if ((typeof subject != 'undefined') && isString(subject) && (subject.length > 0))
    {
      //subject = '___' + RemoteActor.encode(subject);
      subject = (Actor.UserNameSpace != null) ? Actor.UserNameSpace + subject : subject;
      msgSubject = subject;
      VideoMsgProducer.lastMsgName = subject;
      directorTrace('VideoMsgProducer.recordAs msgSubject: ' + msgSubject);
      this.record();
    }
  }

  this.getLastMsgName = function() // USER API
  {
    return VideoMsgProducer.getLastMsgName();
  }

  // aliases
  
  this.record = function() {return this.startCapture();}
  this.live = function() {this.startPreview();}

  this.getActorContextIndex = function()
  {
    return Actor.getCameraCaptureActor().getContextIndex();
  }

  this.getActorName = function()
  {
    return Actor.getCameraCaptureActor().getName();
  }

  this.buildEventDescriptor = function(event,optionalArgs)
  {
    return ContextEventDescriptor.create(event,this.getActorContextIndex(),this.getActorName(),optionalArgs);
  }

  this.configureEncode = function(project)
  {
    var resolutionWidth;
    var resolutiunHeight;
    if (!Cvm.isFvMode())
    {
      resolutionWidth = 320;
      resolutionHeight = 240;
    }
    else
    {
      resolutionWidth = FvDefaults.recordWidth;
      resolutionHeight = FvDefaults.recordHeight;
    }
    directorTrace('VideoMsgProducer.configureEncode' +
		  ' resolutionWidth: ' + resolutionWidth +
		  ' resolutionHeight: ' + resolutionHeight);
    project.setParameter('video', 'resolutionWidth', resolutionWidth);
    project.setParameter('video', 'resolutionHeight', resolutionHeight);
  }
}


VideoMsgProducer.lastMsgName = null;
VideoMsgProducer.getLastMsgName = function() // USER API
{
  return VideoMsgProducer.lastMsgName;
}


