//elem = string (elementId to make TextArea)
var TextArea = function(elem) {
  this.elem = $('#' + elem);
  var that = this;
//  this.elem = new Ox.Input({'type': 'textarea', 'id': 'textArea'}).attr("id", elem).appendTo('#txtWrapper');
  this.hasFocus = false;  
  this.width = this.elem.width();
  this.spans = [];
  this.init()  
  }

TextArea.prototype.init = function() {
  var that = this;
  var e = this.elem;
  var tc;
  e.focus(function() {
    that.hasFocus = true;
    }).blur(function() {
    that.hasFocus = false;
    });
  e.dblclick(function() {
    if (tc = that.isTc()) {
      Video.set(tc);
      } else {
      that.insertTc();
      }
    Video.togglePause();
    });
  }


//returns tc in ms if cursor is at a time-code, else returns false
TextArea.prototype.isTc = function() {
  var that = this;
  var e = this.elem;
  var eDom = e.get(0);  
  var val = e.val();
  var pos = eDom.selectionStart;
  var word = this.getWord(pos);
  if (isValidTimecode(word)) {
    return npt2ms(word);
    } else {
    return false;
    }
  }

//inserts current timecode at cursor position
TextArea.prototype.insertTc = function() {
  var that = this;
  var e = that.elem;
  var eDom = e.get(0);
  var scrollTop = eDom.scrollTop;
  var val = this.elem.val();
  var pos = eDom.selectionStart;
  var tcNpt = ms2npt(Video.get());
  var newVal = val.substring(0,pos) + "\n" + tcNpt + "\n" + val.substring(pos, val.length);   
  e.val(newVal);
  e.focus();
  eDom.selectionStart = pos + tcNpt.length + 1;
  eDom.selectionEnd = pos + tcNpt.length + 1;
  eDom.scrollTop = scrollTop + 15;   
  }

//gets the word at character pos (int) [in val (str)]
TextArea.prototype.getWord = function(pos, val) {
  if (!val) {
    val = this.elem.val();
    }
  var c;
  var i = pos;
  var j = pos;
  while (c != " " && c != "\n") {
    if (i==0) {
      i = -1;
      break;
      }   
    i--;      
    c = val.substring(i,i+1);    
    }
  var firstLetter = i+1;
  var d;
  while (d != " " && d != "\n") {
    if (j >= val.length) {
      break;
      }
    j++;    
    d = val.substring(j,j+1);    
    }
  var lastLetter = j;
  var word = val.substring(firstLetter, lastLetter);
  return word;
  }

function cleanNewlines(str) {
  var s = str.replace('\r\n|\r|\n', '\n');
  return s;
  }

//takes an srt as param, loads into txtarea
TextArea.prototype.fromSrt = function(srt) {
  this.spans = [];  
  srt = cleanNewlines(srt);
  srt = strip(srt);
  var srt_ = srt.split('\n\n');
  for(s in srt_) {
    st = srt_[s].split('\n');
    if(st.length >=2) {
      var n = st[0];
      var i = strip(st[1].split(' --> ')[0]);
      var o = strip(st[1].split(' --> ')[1]);
      var t = st[2];
      if(st.length > 2) {
        for(j=3; j<st.length;j++) {
          t += '\n'+st[j];
          }
        }
        var is = toSeconds(i);
        var os = toSeconds(o);
        this.spans[this.spans.length] = new Span(is, os, t, spans.length);
        }
     }
  var out = '';
  var spans = this.spans;
  for (span in spans) {
    if (spans.hasOwnProperty(span)) {
      var sp = spans[span];
      out += ms2npt(sp.tcInMs) + "\n";
      out += sp.text;
      out += "\n";
//If the outpoint of current span is equal to inpoint of next span, dont print out timecode, and just add the extra \n to go to next span.
      if (span < spans.length - 1) {
        var p = parseInt(span) + 1;
        if (spans[p].tcInMs != sp.tcOutMs) {
          out += ms2npt(sp.tcOutMs) + "\n\n";
          } else {
          out += "\n";
          }
        }
      }
    }
  this.elem.val(out); 
  }

function strip(s) {
  return s.replace(/^\s+|\s+$/g,"");
  }

function toSeconds(t) {
  var s = 0.0;
  if(t) {
    var p = t.split(':');
    for(i=0;i<p.length;i++) {
      s = s * 60 + parseFloat(p[i].replace(',', '.'))
      }
    }
  return s;
  }

function spansToSrt(arr, fmt, start_no) {
  if (typeof start_no == 'undefined') {
    start_no = 1;
    }
  var srt = '';
  var srtNo = start_no;
  for (var k=0; k < arr.length; k++) {
    var s = arr[k];
    if (s.text.trim() == '') {      
      } else {
      var text = s.text.trim();
      linebreaksRegex = new RegExp('\n+', "g")
      text = text.replace(linebreaksRegex, "\n");
      if (!s.tcOutMs) {
        s.tcOutMs = parseInt(Video.player.duration * 1000);
        }
      if (fmt == 'srt') {
        srt += srtNo + " ";
        srt += "\n";
        srt += "0" + ms2npt(s.tcInMs).replace(".", ",") + " --> " + "0" + ms2npt(s.tcOutMs).replace(".", ",");
        srt += "\n";
        srt += text;
        srt += "\n\n";
        }
      else if (fmt == 'enc') {
        srt += srtNo + ms2frames(s.tcInMs) + " " + ms2frames(s.tcOutMs) + " " + text;
        srt += "\n\n";
        }
      srtNo++;
      }
    }
  return srt;
  }

//returns textarea formatted to .srt
TextArea.prototype.toSrt = function(fmt) {
  if (!fmt) var fmt = 'srt';
  var text = cleanNewlines(this.elem.val());
  var lines = [];
  lines = text.split("\n");
  var i=0;
  var j=0;
  var spans = this.spans;
  while (i < lines.length) {
    var l = lines[i];
    if (isValidTimecode(l.trim())) {
      var tcIn = l.trim();
      var t = "";
      var thisLine = '';
      while (!isValidTimecode(thisLine.trim())) {
        i++;
        if (i >= lines.length) {
          break;
          }
        thisLine = lines[i];
        if (!isValidTimecode(thisLine.trim())) {
          t += thisLine + "\n";
          }       
        }
      spans[j] = new Span(tcIn, thisLine, t, j);
      j++;
      } else {
      i++;
      }
    }
  this.spans = spans;
  var srt = spansToSrt(spans, fmt);
//  console.log(srt);
  return srt;
  }

//Using spans as GLOBAL is ridiculous - please fix.
TextArea.prototype.addTime = function(ms, start_no) {
//  console.log(ms);
  this.toSrt();
  var s = [];
  var spans = this.spans;
  for (var i=0; i < spans.length;i++) {
    s[i] = {
      index: i,
      tcOutMs: spans[i].tcOutMs + ms,
      text: spans[i].text,
      tcInMs: spans[i].tcInMs + ms
      }
    }
  return spansToSrt(s, 'srt', start_no)   
  }

//creates new Span (tcIn and tcOut in npt format)
var Span = function(tcIn, tcOut, text, index) {
  this.index = index;
  this.tcOutMs = npt2ms(tcOut);
  this.text = text;
  this.tcInMs = npt2ms(tcIn);
  }

var SeekBar = function(elem) {
  this.elem = $('#' + elem);
  this.pointerId = "seekPointer";
  this.width = this.elem.width();
  this.init()
  }

SeekBar.prototype.init = function() {
  var that = this;
  var e = $('<div />');
  e.attr("id", that.pointerId);
  e.draggable({
    containment: 'parent',
    axis: 'horizontally',
    drag: function() {
      clearInterval(videoListener);
      var pos = that.get();
      $('#timeCode').html(ms2npt(pos));
      },
    stop: function() {
      var pos = that.get();
      Video.set(pos);
      videoListener = setInterval(Video.listener, 250);
      }
    });  
  that.elem.append(e);
  this.pointerElem = e;
  }

//gets current time-code (int) of seekbar position
SeekBar.prototype.get = function() {
  var cssPos = parseInt(this.pointerElem.css("left"));
  var pos = parseInt((cssPos / this.width) * (Video.player.duration * 1000));
  return pos;
  }

//sets seek bar css pos according to current time-code
SeekBar.prototype.set = function(ms) {
  var cssPos = parseInt(((ms / 1000) / Video.player.duration) * this.width);
  this.elem.css("left", cssPos + "px");
  }

/*
var KeyboardController = function() {
  this.
  }
*/

function loadSrt(filename) {
//  alert("hmm.. you have a .srt file but not a txt file - this is a bug. sorry.");
  var txt = mozillaLoadFile(filename);
  textArea.fromSrt(txt);  
  }

function loadMeta(filename) {
  var m = mozillaLoadFile(filename);
  }

function loadSrtTxt(filename) {
  var txt = mozillaLoadFile(filename);
  $('#txt').val(txt);
  }