var CueEditor = Class.create(
{

  initialize :  function(waveform_div, cue_div, options)
  {
    this.editable = false;
    this.waveform = $(waveform_div);
    this.waveform.offset_left = Position.cumulativeOffset(this.waveform)[0];
	 if (this.waveform.clientLeft) {
	   this.waveform.margin_left = this.waveform.clientLeft;
		this.waveform.margin_right = this.waveform.margin_left;
    } else {
	   this.waveform.margin_left = parseFloat(this.waveform.getStyle('margin-left'));
      this.waveform.margin_right = parseFloat(this.waveform.getStyle('margin-right'));
    }
	 this.waveform.base_offset = this.waveform.offset_left + this.waveform.margin_left;
	 this.max_width = this.waveform.getWidth() - (this.waveform.margin_left + this.waveform.margin_right);
    this.cue = $(cue_div);
	 this.trough = $(options.trough_div);
	 this.f_cue_start_str = options.form_cue_start;
	 this.f_cue_stop_str = options.form_cue_stop;
	 this.f_cue_enable_str = options.form_cue_enable;
    this.f_cue_start = $(options.form_cue_start);
    this.f_cue_stop = $(options.form_cue_stop);
	 this.f_cue_enable = $(options.form_cue_enable);
    this.duration = options.total_duration;
	 if (typeof(options.player_callback) == 'function') {
	   this.playerCallback = options.player_callback;
	 }
	 this.is_attached = false;
    this.cues = new Array();
  },
  add_to_trough : function (options)
  {
    this.cues.push({id: options.comment_id, start: options.cue_start, stop: options.cue_stop, message: options.comment_message});
    this.draw_trough();
  },
  trough_attach : function (e, options)
  {
    this.attach(options);
  },
  draw_trough : function ()
  {
    if (this.trough) {
		var self = this;
		var cue_h = 10;
		for (var l=0; l < this.cues.length; ++l) {
		  cue = this.cues[l];
		  // if a cue already has a div, don't draw it
		  if (typeof(cue.div) != 'undefined') {
		    continue;
		  }
		  set_style = {
		      cursor: "pointer",
		      position: "absolute",
			   backgroundColor:"#07d", 
				opacity: "0.5",
				top: String(cue_h*l) + "px",
				height: String(cue_h) + "px",
				left: String(self.time_to_screen(cue.start)) + "px",
				width: String(self.time_to_screen(cue.stop) - self.time_to_screen(cue.start)) + "px"
          };
		  ndiv = Element.extend(document.createElement('div')).addClassName('trough_cue').setStyle(set_style);
		  ndiv.title = cue.message;
		  self.trough.appendChild(ndiv);
		  //ndiv.insert($('trough_start'), {position: "after"});
		  cue.div = ndiv;
		  cue.mouseDownEvent = this.trough_attach.bindAsEventListener(this, {begin: cue.start, end: cue.stop, message: cue.message});
        Event.observe(ndiv, "mousedown", cue.mouseDownEvent, false);
		}
		this.trough.setStyle({height: String(this.cues.length * cue_h) + "px"});
	 }
  },
  attach : function(options) 
  {
    if (typeof(this.f_cue_start) == 'undefined' || this.f_cue_start == null) {
	  this.f_cue_start = $(this.f_cue_start_str);
	  this.f_cue_stop = $(this.f_cue_stop_str);
	  this.f_cue_enable = $(this.f_cue_enable_str);
	 }
    var cue_l = 0;
    var cue_r = this.duration;
	 this.cue.title = "";
    if (typeof(options) != 'undefined') {
	   if (options.begin) {
        cue_l = options.begin;
      }
      if (options.end) {
        cue_r = options.end;
	   }
      this.editable = options.editable || false;
      if (options.message) {
        this.cue.title = options.message;
		}
	 }
	 else {
	   this.editable = true;
	 }
	 this.cue.setStyle({   zIndex: 99, 
                          left: String(this.time_to_screen(cue_l)) + "px", 
                          width: String(this.time_to_screen(cue_r) - this.time_to_screen(cue_l)) + "px",
                          backgroundColor: (this.editable ? "#f00" : "#07d"),
		                    visible: true
							 });
	 
	 this.is_attached = true;
    
	 if (this.editable) {
      this.f_cue_start.value = '0.';
      this.f_cue_stop.value = String(duration);
	   this.f_cue_start.type = 'text';
	   this.f_cue_stop.type = 'text';
		this.f_cue_enable.value = null;
	   this.f_cue_enable.type = 'checkbox';
      this.f_cue_enable.checked = 'yes';
		
		this.onCueMouseDownBind = this.onCueMouseDown.bindAsEventListener(this);
		this.onCueMouseUpBind = this.onCueMouseUp.bindAsEventListener(this);
		this.onCueMouseOverBind = this.onCueMouseOver.bindAsEventListener(this);

      Event.observe(this.cue, "mousedown", this.onCueMouseDownBind, false);
	   Event.observe(document, "mouseup", this.onCueMouseUpBind, false);
      Event.observe(this.waveform, "mousemove", this.onCueMouseOverBind, false);
    }
	 else {
	   this.onNoEditCueMouseDownBind = this.onNoEditCueMouseDown.bindAsEventListener(this);
	   Event.observe(this.cue, "mousedown", this.onNoEditCueMouseDownBind, false);
	 }
	this.onNonCueMouseDownBind = this.onNonCueMouseDown.bindAsEventListener(this);
	Event.observe(this.waveform, "mousedown", this.onNonCueMouseDownBind, false);
  },
  detach : function()
  {
      this.is_clicked = false;
      Event.stopObserving(this.cue, "mousedown", this.onNoEditCueMouseDownBind, false);
		Event.stopObserving(this.cue, "mousedown", this.onCueMouseDownBind, false);
	   Event.stopObserving(document, "mouseup", this.onCueMouseUpBind, false);
      Event.stopObserving(this.waveform, "mousemove", this.onCueMouseOverBind, false);
	   Event.stopObserving(this.waveform, "mousedown", this.onNonCueMouseDownBind, false);
		if (this.cue) {
        this.cue.setStyle({ visible: false, left: "0px", width: "0px" });
		  if (this.editable) {
		    this.f_cue_enable.value = '0';
		    this.f_cue_enable.type = 'hidden';
			 this.f_cue_start.type = 'hidden';
			 this.f_cue_stop.type = 'hidden';
		  }
		}
		this.editable = false;
		this.is_attached = false;
  },
  float_to_string : function (inval, num_digits)
	{
    var v = String(inval);
	  while(v.length  < num_digits) {
	    v = "0" + v;
	  }
	  return v;
	},
  time_to_screen : function(time)
  {
    return time/this.duration * this.max_width;
  },
  screen_to_time : function(screen)
  {
    this.waveform.offset_left = Position.cumulativeOffset(this.waveform)[0];
    var base_offset = this.waveform.offset_left;
    var pos_n = (screen - base_offset) / this.max_width;
    return pos_n * this.duration;
  },
  getAbsLeft : function()
  {
    return Position.cumulativeOffset(this.cue)[0];
  },
  getAbsRight : function()
  {
    return this.getAbsLeft() + Element.getWidth(this.cue);
  },
  isNearLeft : function(pos)
  {
    return Math.abs(pos - this.getAbsLeft()) < 10;
  },
  isNearRight : function (pos)
  {
    return Math.abs(pos - this.getAbsRight()) < 10;
  },
  onNoEditCueMouseDown : function(e)
  {
    if (typeof(this.playerCallback) == 'function') {
      this.playerCallback(this.screen_to_time(Position.cumulativeOffset(this.cue)[0]));
	 }
	 Event.stop(e);
  },
  onCueMouseDown : function(e)
  {
    if (this.editable) {
    this.cue.is_clicked = true;
    var mouseX = Event.pointerX(e);
    if (this.isNearLeft(mouseX)) {
      this.cue.is_edit_left = true;
      Event.observe(document, "mousemove", this.onCueMouseMove.bindAsEventListener(this), true);
    }
    else if (this.isNearRight(mouseX)) {
      this.cue.is_edit_left = false;
      Event.observe(document, "mousemove", this.onCueMouseMove.bindAsEventListener(this), true);
    }
	 else {
	   this.cue.is_clicked = false;
		if (typeof(this.playerCallback) == 'function') {
		  this.playerCallback(screen_to_time(Position.cumulativeOffset(this.cue)[0]));
		}
	 }
    Event.stop(e);
	 }
  },
  onNonCueMouseDown : function(e)
  {
    if (this.is_attached) {
	   this.detach();
	 }
  },
  onCueMouseOver : function(e)
  {
    var mouseX = Event.pointerX(e);
	 var mouseY = Event.pointerY(e);

	 if (Position.within(this.waveform, mouseX, mouseY))
	 {
      if (this.editable) {
        var mouseX = Event.pointerX(e);
        if (this.isNearLeft(mouseX)) {
          this.cue.setStyle({cursor:"w-resize"});
        } 
        else if (this.isNearRight(mouseX)) {
          this.cue.setStyle({cursor:"e-resize"});
        }
        else {
          this.cue.setStyle({cursor:"crosshair"});
        }
      }
		else if (Position.within(this.cue, mouseX, mouseY)) {
        this.cue.setStyle({cursor:"crosshair"});
		}
    }
  },
  onCueMouseUp : function(e)
  {
    if (this.cue.is_clicked) {
      Event.stopObserving(document, "mousemove", this.onCueMouseMove.bindAsEventListener(this), true);
      this.cue.is_clicked = false;
      Event.stop(e);
    }
  },
  onCueMouseMove : function(e)
  {
    if (this.cue.is_clicked && this.editable)
	 {
    this.waveform.offset_left = Position.cumulativeOffset(this.waveform)[0];
    var mouseX = Event.pointerX(e);
    var old_width = Element.getWidth(this.cue);
    var base_offset = this.waveform.offset_left + this.waveform.margin_left;
    var old_left_abs = parseFloat(this.cue.getStyle('left')) + base_offset; 
    var new_left = mouseX - base_offset;
    
	 var old_left_rel = old_left_abs - base_offset;
	 var old_right_abs = old_left_abs + old_width;;
	 var old_right_rel = old_right_abs - base_offset;

    if (this.cue.is_edit_left) {
      if (new_left < 0) {
        mouseX -= new_left;
        new_left = 0;
      }
      if (new_left >= old_left_rel + old_width) {
        new_left = old_left_rel -1;
        Event.stop(e);
        return;
      }
		var oleft = parseFloat(this.cue.getStyle('left'));
      this.cue.setStyle({left: String(new_left) + "px"});
      this.cue.setStyle({width: String(old_width + (oleft - new_left)) + "px"});
      this.f_cue_start.value = String(this.screen_to_time(new_left + base_offset ));
    }
    else {
      var new_width = Event.pointerX(e) - Position.cumulativeOffset(this.cue)[0];
      if (new_width > this.max_width - old_left_rel) {
        new_width = this.max_width - old_left_rel;
      }
      this.cue.setStyle({width: String(new_width) + "px"});
      this.f_cue_stop.value = String(this.screen_to_time(base_offset + old_left_rel + new_width));
    }
    Event.stop(e);
  }
  }
}
);
