/**
 * @author jgornick
 */

Element.addMethods(['TABLE', 'THEAD', 'TBODY', 'TFOOT'], {
  addRow: function(element, options)
  {
    this.options = {
      index: 0,
      cells: $A()
    };
    Object.extend(this.options, options || { });
    
    element = $(element);

    // First, add the row to the table.
    var row = $(element.insertRow(this.options.index));
    
    this.options.cells.each(function(cell, index)
    {
      var rowCell = $(row.insertCell(index));

      $H(cell).each(function(attribute) 
      {
        switch (attribute[0])
        {
          case 'innerHTML':
	          rowCell.update(attribute[1]);
            break;
          case 'className':
	          rowCell.addClassName(attribute[1]);
            break;
          default:
            rowCell.writeAttribute(attribute[0], attribute[1]);          
        }
      });
    });
    
    return row;
  }
});

Element.addMethods(['INPUT', 'SELECT', 'TEXTAREA'], {
  canFocus: function(element)
  {
    if (element.disabled) return false;
    
    while ((element = element.parentNode) && element != document.body)
      if (!Element.visible(element))
        return false;

    return true;
  },
  
  copyToClipboard: function(element, swf) 
  {
    // Uses a combination of:
    // http://www.jeffothy.com/weblog/clipboard-copy/
    // http://www.rodsdot.com/ee/cross_browser_clipboard_copy_with_pop_over_message.asp
    if (Object.isUndefined(swf)) swf = '_clipboard.swf';
    
    element = $(element);
    
    if (window.clipboardData) 
      window.clipboardData.setData("Text", element.getValue());
    else
    {
      if(!$('flash_clipboard_container'))
        $(document.body).insert({
          top: new Element('div', { id: 'flash_clipboard_container' })
        });

      $('flash_clipboard_container').setStyle({
        position: 'absolute',
        top: '-9999px',
        left: '-9999px'
      });
      
      var content = encodeURIComponent(element.getValue());

      if (!(typeof SWFObject == "undefined"))
      {
        var so = new SWFObject(swf, 'copy_contents', '0', '0', '4');
        so.addVariable('clipboard', content);
        so.write('flash_clipboard_container');
      }
      else
      {
        var object = new Element('object', {
          width: 0, 
          height: 0, 
          name: 'copy_contents', 
          id: 'copy_contents',
          classid: 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'
        });
        
        object
          .insert(new Element('param', {
            name: 'movie',
            value: swf
          }))
          .insert(new Element('param', {
            name: 'flashvars',
            value: 'clipboard=' + content
          }))
          .insert(new Element('param', {
            name: 'quality',
            value: 'high'
          }));          

        var embed = new Element('embed', {
          width: 0, 
          height: 0, 
          flashvars: 'clipboard=' + content, 
          quality: 'high', 
          name: 'copy_contents', 
          id: 'copy_contents', 
          src: swf, 
          type: 'application/x-shockwave-flash'
        });
        
        object.insert(embed);
        
        $('flash_clipboard_container').update(object);
      }
    }
  }
});

var URI = Class.create({
	_regExp : /^((\w+):\/\/)?((\w+):?(\w+)?@)?([^\/\?:]+):?(\d+)?(\/?[^\?#]+)?\??([^#]+)?#?(\w*)/,

	initialize: function(uri) 
  {
		if (typeof(uri) == 'undefined')
		  r = [];
		else
		  var r = uri.match(this._regExp);
		
		if (!r) throw "Invalid URI"
		
    this.url         = this._getVal(r,0);
		this.protocol	   = this._getVal(r,2);
		this.username	   = this._getVal(r,4);
		this.password	   = this._getVal(r,5);
		this.host		     = this._getVal(r,6);
		this.port		     = this._getVal(r,7);
		this.pathname    = this._getVal(r,8);
		this.query       = (this._getVal(r,9)) ? this._getVal(r,9).toQueryParams() : null;
		this.fragment	   = this._getVal(r,10);	
	},
	
	_getVal : function(r, i) 
  {
		if(!r) return null;
		return (typeof(r[i]) == 'undefined' ? null : r[i]);
	},
	
  _isEmptyOrNull: function(v)
  {
  	// Null
    if (v == null) return true;
    // Empty
    if (v.strip().blank()) return true;
    
    return false;    
  },
   
  toString: function()
  {
		var output = $A();
    
    output.push((this._isEmptyOrNull(this.protocol)) ? '' : this.protocol + '://');
    output.push((this._isEmptyOrNull(this.username)) ? '' : this.username);
    output.push((this._isEmptyOrNull(this.password)) ? (this._isEmptyOrNull(this.username)) ? '' : '@' : ':' + this.password + '@');
    output.push((this._isEmptyOrNull(this.host)) ? '' : this.host);
    output.push((this._isEmptyOrNull(this.port)) ? '' : ':' + this.port);
    output.push((this._isEmptyOrNull(this.pathname)) ? '' : this.pathname);
    output.push((this._isEmptyOrNull($H(this.query).toQueryString())) ? '' : '?' + decodeURIComponent($H(this.query).toQueryString()));    
    output.push((this._isEmptyOrNull(this.fragment)) ? '' : '#' + this.fragment);
    
    return output.join('');
  }
});

function $U(uri) 
{
  return new URI(uri);
}

////////////////////////////////////////////////////////////////////////////////

var AutobahnHDPlayerWizard = Class.create(Wizard, {
  initialize: function($super, container, options)
  {
    $super(container, options);
    this.setupPage1();
    this.setupPage2();   
    this.setupPage3();    
    this.setupPage4();

		Validation.addAllThese([
    	['validate-url', 'Please enter a valid URL (e.g. http://getautobahn.com).', function (v) {
        return Validation.get('IsEmpty').test(v) || /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)*)(:(\d+))?\/?/i.test(v)
 			}],        
			['validate-video-width', 
       'The video width must be between 1 and 1920.', 
       {
			   min: 1,
         max: 1920
       }
			],
			['validate-video-height', 
       'The video height must be between 1 and 1080.', 
       {
			   min: 1,
         max: 1080
       }
			],
			['validate-hex', 
       'The value must be a HEX value - FFFFFF.', 
       {
			   pattern: new RegExp('^[0-9a-fA-F]{6}')
       }
			]         
     ]); 
  },
  
  _onPageChange: function($super, index)
  {
    switch (index)
    {
      case 0:
        break;
      case 1:
        if (!this.validatePage1()) return false;
        this.updatePage2();
        break;
      case 2:
        if (!this.validatePage2()) return false;
        break;
      case 3:
        if (!this.validatePage3()) return false;
        this.updatePage4();
        break;        
    }
    
    if (!$super(index)) return false;
    
    return true;
  },

  /*
   * Page 1
   */
  setupPage1: function()
  {
    var table = $$('#' + this.pages[0].el.id + ' table')[0];
    
    this._addTableHeaderRow(table);
    this._addDefaultTableRow(table);
    this._addTableFooterRow(table);
    
    // Setup validation for form
    this.page1Validator = new Validation('setup_videos_form', { });
  },
  
  validatePage1: function()
  {
    return this.page1Validator.validate();
    return true;
  },
  
  _buildMediaGroupXML: function()
  {
    var table = $$('#' + this.pages[0].el.id + ' table')[0];
    var values = $A();
    
    $A(table.tBodies[0].rows).each(function(row) 
    {
      var rowValues = row.select('input');
      values.push({
        video_url: $F(rowValues[1]).stripScripts().stripTags(),
        bitrate: parseInt($F(rowValues[2]).stripScripts().stripTags()) * 1000, // Values are in Kbps, so * 1000.
        smm_url: $F(rowValues[3]).stripScripts().stripTags()      
      })
    });
        
    var xml = $A();
    xml.push('<?xml version="1.0" encoding="utf-8"?>');
    xml.push('<MediaGroup>');
    
    values.each(function(value) 
    {
      var item = $A()
      item.push('<MediaStreamMetadata ');
      item.push('uri="#{video_url}" ');
      item.push('bitRate="#{bitrate}" ');
      item.push('mediaType="flv">');     
      item.push('<SeekIndex uri="#{smm_url}" />');
      item.push('</MediaStreamMetadata>');
      
      xml.push(item.join('').interpolate(value));
    });
    
    xml.push('</MediaGroup>');
    
    return xml.join('\n');
  },
  
  _addTableHeaderRow: function(table)
  {
    var row = [];
    row.push({className: 'default-video', innerHTML: 'Default'});
    row.push({className: 'video-url', innerHTML: 'Video URL'});
    row.push({className: 'bitrate', innerHTML: 'Bitrate (Kbps)'})
    row.push({className: 'smm-url', innerHTML: '<a href="http://blog.getautobahn.com/">SMM URL</a>'})    
    row.push({className: 'remove-row', innerHTML: ''})    
    
    return $(table.tHead).addRow({
      cells: row
    });    
  },
  
  _addDefaultTableRow: function(table)
  {
    var row = [];
    row.push({className: 'default-video', innerHTML: '<input type="checkbox" />'});
    row.push({className: 'video-url', innerHTML: '<input type="text" class="required validate-url" value="http://" />'});
    row.push({className: 'bitrate', innerHTML: '<input type="text" class="required validate-number" />'});
    row.push({className: 'smm-url', innerHTML: '<input type="text" class="required validate-url" value="http://" />'});
    row.push({className: 'remove-row', innerHTML: '<div class="delete" />'});
    
    var lastRow = $A(table.tBodies[0].rows).last();
    var rowIndex = lastRow ? lastRow.rowIndex : 0;

    var row = $(table.tBodies[0]).addRow({
      index: rowIndex,
      cells: row
    });
    
    if (table.tBodies[0].rows.length == 1) row.down('.default-video input').setValue(true);
    
    row.select('input').invoke('identify');
    
    row.down('.default-video input').observe('click', this._setDefaultVideo.bind(this));
    
    // Now let'sobserve the click on the delete row image
    row.down('.remove-row').observe('click', this._removeRow.bind(this));
    
    // Focus newly added row first input.
    if (row.down('input[type=text]').canFocus()) 
      row.down('input[type=text]').focus();
    
    return row;
  },

  _addTableFooterRow: function(table)
  {
    var row = [];
    row.push({colspan: 5, innerHTML: '<ul><li><span>Add Video</span></li></ul>'});
    
    var row = $(table.tFoot).addRow({
      cells: row
    });
    
    // Observe a click on the li which will add a row.
    row.down('li').observe('click', this._addRow.bind(this));
    
    return row;
  },

  _addRow: function(e)
  {
    var table = $$('#' + this.pages[0].el.id + ' table')[0];
    return this._addDefaultTableRow(table);
  },
    
  _removeRow: function(e)
  {
    var rowIndex = Event.element(e).up('tr').rowIndex - 1;
    var table = $$('#' + this.pages[0].el.id + ' table')[0];
    
    if (table.tBodies[0].rows.length > 1)
      table.tBodies[0].deleteRow(rowIndex);
    
    // If the user removes the default video, select the video before it.  
    var defaultInputs = $$('#' + this.pages[0].el.id + ' .default-video input');
    if (defaultInputs.findAll(function(input) { return $F(input) == 'on' }).length == 0) 
    {
      rowIndex--; // Set the row index to the previous item
      rowIndex = (rowIndex >= 0) ? rowIndex : 0; // Check to make sure we don't go below 0
      $(table.tBodies[0].rows[rowIndex]).down('.default-video input').setValue(true);
      return;
    }
    
  },
  
  _setDefaultVideo: function(e)
  {
    var defaultInputs = $$('#' + this.pages[0].el.id + ' .default-video input');
    
    defaultInputs.invoke('setValue', false);

    Event.element(e).setValue(true);
  },

  /*
   * Page 2
   */
  setupPage2: function()
  {
    var page2 = this.pages[1].el;

    // Setup validation for form
    this.page2Validator = new Validation('media_group_descriptor_form', { });
    
    var form = $('media_group_descriptor_form');
    
    // Setup each form element.       
    form.getElements().each(function(el)
    {
      switch (el.id)
      {
        case 'media_group_url':
          el.addClassName('validate-url');
          el.setValue('http://');
          break;
      }
    });     
    
    // Observe a click on the li to copy the contents to clipboard.
    page2.down('li.copy').observe('click', function() 
    {
      var textarea = $$('#' + page2.id + ' textarea')[0];      
      textarea.copyToClipboard($('_base_url').innerHTML + '/swf/_clipboard.swf');
    });
    
    page2.down('li.download').observe('click', function() 
    {
      var query = {
        filename: 'media-descriptor',
        filetype: 'xml',
        content: $F('autobahn_url_xml')
      }
      window.location = $('_base_url').innerHTML + '/inc/download.php?' + $H(query).toQueryString();
    });
  },
  
  updatePage2: function()
  {
    var textarea = $$('#' + this.pages[1].el.id + ' textarea')[0];
    textarea.setValue(this._buildMediaGroupXML());
  },
  
  validatePage2: function()
  {
    return this.page2Validator.validate();
  },
  
  /*
   * Page 3
   */  
  setupPage3: function()
  {
    new Form.Element.Observer('autoplay', 0.1, function(form, value)
    {
      value == 'on' ? $('image_url').disable() : $('image_url').enable();
      value == 'on' ? $('caption').disable() : $('caption').enable(); 
    });
     
    // Add a className of row to each immediate child in the fieldset.
    $$('div.form-container form > div').invoke('writeAttribute', 'class', 'row');
    
    // Setup validation for form
    this.page3Validator = new Validation('player_options_form', { });
    
    var form = $('player_options_form');
    
    // Setup each form element.       
    form.getElements().each(function(el)
    {
      switch (el.id)
      {
        case 'video_width':
          el.addClassName('required validate-video-width');
          el.setValue('320');
          break;
        case 'video_height':
          el.addClassName('required validate-video-height');
          el.setValue('180');
          break;
        case 'autoplay':
          el.checked = false;
          break;
        case 'image_url':
          el.addClassName('validate-url');
          break;
        case 'background_color':
          el.addClassName('validate-hex');
          el.setValue('FFFFFF');
          break;           
      }
    });    
  },
  
  validatePage3: function()
  {
    return this.page3Validator.validate();
  },

  /*
   * Page 4
   */  
  setupPage4: function()
  {
    var page4 = this.pages[3].el;

    var select = page4.down('select');
    var textarea = page4.down('textarea');
        
    select.observe('change', this._sourceTypeChange.bind(this));
               
    // Observe a click on the li to copy the contents to clipboard.
    page4.down('li.copy').observe('click', function() 
    {
      var textarea = page4.down('textarea');      
      textarea.copyToClipboard($('_base_url').innerHTML + '/swf/_clipboard.swf');
    });
       
    page4.down('li.download').observe('click', function() 
    {
      var query = {
        filename: 'player-source',
        filetype: 'html',
        content: $F('player_source_textarea')
      }
      window.location = $('_base_url').innerHTML + '/inc/download.php?' + $H(query).toQueryString();
    });
  },
  
  _sourceTypeChange: function()
  {
    var page4 = this.pages[3].el;
    var textarea = page4.down('textarea');
    var select = page4.down('select');
      
    var defaultInputs = $$('#' + this.pages[0].el.id + ' .default-video input');
	  var defaultVideo = defaultInputs.findAll(function(input) { return $F(input) == 'on' })[0];
    
    var defaultVideoUrl = $F(defaultVideo.up('tr').down('.video-url input'));
    var mediaGroupUrl = $F('media_group_url');
    
    var autobahnVideoUrl = 'http://local.swarmcast.net:8001/?swarm:mediagroup_uri=' + mediaGroupUrl;

    var values = $('player_options_form').serialize(true);
            
    values.width = parseInt(values.video_width) + 14;
    values.height = parseInt(values.video_height) + 42;
    values.autoplay = (values.autoplay == 'on') ? true : false;
    values.allow_fullscreen = true;
    values.id = 'AutobahnHDPlayer';
    values.name = 'AutobahnHDPlayer';
    
    values.src = 'http://' + getEnvironment() + '.swarmcast.com/swf/AutobahnHDPlayer.swf';
    
    if (getEnvironment() == 'production')
      values.src = 'http://www.swarmcast.com/swf/AutobahnHDPlayer.swf';

    values.application_type = 'application/x-shockwave-flash';
    values.flash_version = 9;
    values.default_video_url = defaultVideoUrl;
    values.media_group_url = mediaGroupUrl;   
    values.autobahn_video_url = autobahnVideoUrl;     
    
    // Go through each value and strip the scripts and tags.
    values = $H(values);
    values.each(function(pair)
    {
      if (typeof pair.value != 'undefined')
        values.set(pair.key, pair.value.toString().stripScripts().stripTags());
    });
 
    if (select.selectedIndex == 0)
      textarea.setValue(this._buildObjectEmbedSource(values));
    else if (select.selectedIndex == 1)
      textarea.setValue(this._buildSWFObjectSource(values));
  },
  
  _buildObjectEmbedSource: function(values)
  {
    var flashvars = $A();
    flashvars.push('vidWidth=#{video_width}&');
    flashvars.push('vidHeight=#{video_height}&');
    flashvars.push('defaultVideoURL=#{default_video_url}&');
    flashvars.push('autobahnVideoURL=#{autobahn_video_url}&');
    flashvars.push('imageURL=#{image_url}&');
    flashvars.push('autoplay=#{autoplay}&');
    flashvars.push('captionText=#{caption}&');
    flashvars.push('bgColor=#{background_color}');
    
    var objectParams = $A();
    objectParams.push('<param value="#{src}" name="movie" />');
    objectParams.push('<param value="##{background_color}" name="bgcolor" />');
    objectParams.push('<param value="high" name="quality" />');
    objectParams.push('<param value="#{allow_fullscreen}" name="allowFullScreen" />');
    objectParams.push('<param value="always" name="allowScriptAccess" />');
    objectParams.push('<param value="' + flashvars.join('').interpolate(values) + '" name="flashvars" />');
    
    var embedTag = $A();
    embedTag.push('<embed'); 
    embedTag.push('width="#{width}"'); 
    embedTag.push('height="#{height}"'); 
    embedTag.push('flashvars="' + flashvars.join('').interpolate(values) + '"');
    embedTag.push('allowscriptaccess="always"'); 
    embedTag.push('allowfullscreen="#{allow_fullscreen}"'); 
    embedTag.push('quality="high"'); 
    embedTag.push('bgcolor="\##{background_color}"'); 
    embedTag.push('name="#{name}"'); 
    embedTag.push('id="#{id}"'); 
    embedTag.push('src="#{src}"'); 
    embedTag.push('type="#{application_type}"'); 
    embedTag.push('/>');        
    
    var objectTag = $A();                
    objectTag.push('<object id="#{id}" height="#{height}" width="#{width}" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">');
    objectTag.push(objectParams.join('\n').interpolate(values));
    objectTag.push(embedTag.join(' ').interpolate(values));
    objectTag.push('</object>');
    
    return objectTag.join('\n').interpolate(values); 

  },
  
  _buildSWFObjectSource: function(values)
  {
    var swfobject = $A();
    swfobject.push('var so = new SWFObject("#{src}", "#{id}", "#{width}", "#{height}", "#{flash_version}", "##{background_color}");');
    swfobject.push('so.addVariable("defaultVideoURL", "#{default_video_url}");');
    swfobject.push('so.addVariable("autobahnVideoURL", "#{autobahn_video_url}");');
    swfobject.push('so.addVariable("vidWidth", "#{video_width}");');
    swfobject.push('so.addVariable("vidHeight", "#{video_height}");');
    swfobject.push('so.addVariable("autoplay", "#{autoplay}");');
    swfobject.push('so.addVariable("imageURL", "#{image_url}");');
    swfobject.push('so.addVariable("captionText", "#{caption}");');
    swfobject.push('so.addVariable("bgColor", "#{background_color}");');
    swfobject.push('so.addParam("allowFullScreen", "#{allow_fullscreen}");');
    swfobject.push('so.addParam("allowScriptAccess", "always");');
    swfobject.push('so.write(el.id);'); 
    
    return swfobject.join('\n').interpolate(values);    
  },
  
  updatePage4: function()
  {
    var page4 = this.pages[3].el;
    var select = page4.down('select');

    select.selectedIndex = 0;
    this._sourceTypeChange();    
  },
    
  validatePage4: function()
  {
    return true;
  },
  
  initTest: function()
  {
    var table = $$('#' + this.pages[0].el.id + ' table')[0];
    
    var values = [
      ['http://showcase.swarmcast.com/Elephants_Dream_320x180_vp6_496Kbps.flv', 496, 'http://showcase.swarmcast.com/Elephants_Dream_320x180_vp6_496Kbps.smm'],
      ['http://showcase.swarmcast.com/Elephants_Dream_320x180_vp6_800Kbps.flv', 800, 'http://showcase.swarmcast.com/Elephants_Dream_320x180_vp6_800Kbps.smm'],
      ['http://showcase.swarmcast.com/Elephants_Dream_320x180_vp6_1200Kbps.flv', 1200, 'http://showcase.swarmcast.com/Elephants_Dream_320x180_vp6_1200Kbps.smm'],
      ['http://showcase.swarmcast.com/Elephants_Dream_1024x576_vp6_1404Kbps.flv', 1404, 'http://showcase.swarmcast.com/Elephants_Dream_1024x576_vp6_1404Kbps.smm']
    ];
    
    $A(table.tBodies[0].rows).each(function(row){
      table.tBodies[0].deleteRow(row);
    });
    
    $A(values).each(function(value, index) {
      var row = this._addRow();
      
      if (index == 0)
        var defaultInput = row.down('.default-video input').setValue('on'); 
      
      row.down('.video-url input').setValue(value[0]);
      row.down('.bitrate input').setValue(value[1]);
      row.down('.smm-url input').setValue(value[2]);
    }.bind(this));
  } 
});
