Event.observe(window, 'load', initialize );

var spEditor;

function initialize(){
  spEditor = new StoryEditor();
  spEditor.loadStoryFromHTML( $( 'spe_content' ) );
}


function uploadCompletedCallback(arg) {
  var obj = eval('('+arg+')');
  $( 'file_uploader' ).hide();
  spEditor.insertIMG( obj );
  
  // image association
  var new_asset_id = new Element( 'input', { 'name': 'asset_ids[]', 'value': obj.asset_id, 'type': 'hidden' } );
  var content_elem = $('content'); // shortcut to form
  Element.insert(content_elem, new_asset_id);
}

function cancelFileUpload(){
  spEditor.cancelInsertIMG();
}



StoryEditor = Class.create({
  initialize:function(){
    this.components = [];
    this.activeComponent = null;
    this.editor = $( 'sp_editor' );
    this.content = $( 'spe_content' );
    this.editBar = $( 'spe_edit_tools' );
    this.selection = new Array;
    this.nextId = 0;
    
    this.editorP = new Element( 'textarea', { 'rows': '15' } );
    this.editorP.onselect = this.handleSelection;
    //this.hilite = new Element( 'div', { 'className':'hilite' } );
    
    this.editor.makePositioned();
    this.content.makePositioned();
    //this.hilite.makePositioned();
  
    Event.observe( this.content, 'click', this.contentClicked.bindAsEventListener( this ) );
  },
 
  handleSelection:function( e ) {
    if(document.selection) {
       spEditor.selection['range'] = document.selection.createRange();
    } else {
       spEditor.selection['before'] = spEditor.editorP.value.substring(0, spEditor.editorP.selectionStart);
       spEditor.selection['inside'] = spEditor.editorP.value.substring(spEditor.editorP.selectionStart, spEditor.editorP.selectionEnd);
       spEditor.selection['after'] = spEditor.editorP.value.substring(spEditor.editorP.selectionEnd,spEditor.editorP.value.length);
    }
  },
 
  contentClicked:function( e ){
    //this.deactivate();
  },
  
  loadStoryFromHTML:function( e ){
    if( cmpnts = e.firstDescendant() ){
      var cmpnts = e.firstDescendant().childElements();
      e.firstDescendant().remove();
      
      for( var i=0,l=cmpnts.length; i<l; i++ ){
        var cmpnt = cmpnts[i];
        
        switch( cmpnt.tagName ) {
          case 'P':
            this.insertComponent( new StoryP( this.getNextId(), cmpnt ) );
            break;
          case 'UL':
            this.insertComponent( new StoryUL( this.getNextId(), cmpnt ) );
            break;
          case 'OL':
            this.insertComponent( new StoryUL( this.getNextId(), cmpnt ) );
            break;
          case 'DIV':
            if( cmpnt.hasClassName( 't-img' ) ){
              this.insertComponent( new StoryIMG( this.getNextId(), cmpnt ) );
            }
            break;      
        }
      }
    }
  },
  
  activateComponent:function( c ){
    if( this.activeComponent != null ){
      if( this.activeComponent.edit ){
        this.unedit();
      }
      this.activeComponent.deactivate();
    }
    
    c.activate();
    this.activeComponent = c;
    
    c.e.insert( { before: this.editBar } );

    if (c.e.tagName.toLowerCase()=='div') {
      $('spe_move_to_top').show();
    } else {
      $('spe_move_to_top').hide();
    }
    this.editBar.show();
  },
  
  insertComponent:function( c ){
    if( this.activeComponent == null ){
      this.content.insert({ bottom: c.e });
      this.components[ this.components.length ] = c;
    } else {
      this.activeComponent.e.insert({ after: c.e });
      
      var olds = this.components;
      var news = [];
      for( var i=0,l=olds.length; i<l; i++ ){
        var old = olds[i];
        news[ news.length ] = old;
        if( old == this.activeComponent ){
          news[ news.length ] = c;
        }
      }
      
      this.components = news;
    }
    
    c.addListener( this );
    this.activateComponent( c );
  },

  moveToTop:function(){
    if( this.activeComponent != null ){
      c = this.activeComponent;
      this.remove( c );
      this.content.insert({ top: c.e });
      this.components.unshift(c );
      this.activateComponent( c );
    }
  },
  
  storyComponentClicked:function( c ){
    this.activateComponent( c );
  },
  
  insertP:function(){
    var c = new StoryP( this.getNextId() );
    c.setText( 'Click the Edit button to edit this text.' );
    this.insertComponent( c );
  },
  
  insertUL:function(){
    var c = new StoryUL( this.getNextId() );
    c.setText( 'Click the Edit button to edit this text.' );
    this.insertComponent( c );
  },
  
  insertOL:function(){
    var c = new StoryOL( this.getNextId() );
    c.setText( 'Click the Edit button to edit this text.' );
    this.insertComponent( c );
  },
  
  prepareInsertIMG:function( obj ){
    $( 'file_uploader' ).show();
  },
  
  prepareChooseIMG:function( obj ){
  	$( 'image_selector' ).toggle();
  },
  
  cancelInsertIMG:function( obj ){
    $( 'file_uploader' ).hide();
  },
  
  insertIMG:function( obj ){
    var c = new StoryIMG( this.getNextId(), obj );
    this.insertComponent( c );
  },

  prepareInsertA:function( obj ){
    if(spEditor.selection['range'] || spEditor.selection['inside'] != '' && spEditor.selection['inside'] != undefined) {
         $( 'hyperlink_selector' ).show();
    }
    spEditor.createSelection(); 
  },

  cancelInsertA:function( obj ){
    $( 'hyperlink_selector' ).hide();
    spEditor.createSelection();
  },

  createSelection:function(){
     if(spEditor.selection['range']) {
     } else if (spEditor.selection['inside'] != '' && spEditor.selection['inside'] != undefined) {
       spEditor.editorP.select();
       spEditor.editorP.selectionStart = spEditor.selection['before'].length;
       spEditor.editorP.selectionEnd = spEditor.selection['before'].length + spEditor.selection['inside'].length;
     }
  },

  clearSelection:function(){
     spEditor.selection = new Array();
  },

  insertA:function(){
    var linkTarget = $('StoryATarget').value != ''? 'target="'+$('StoryATarget').value+'"' : '';

    if(spEditor.selection['range']) {
       spEditor.selection['range'].text = '<a href="'+$('StoryALink').value+'" title="'+$('StoryATitle').value+'" '+linkTarget+'>' + spEditor.selection['range'].text + '</a>';
    }else if (spEditor.selection['inside'] != ''){
      spEditor.editorP.value = spEditor.selection['before']+'<a title="'+$('StoryATitle').value+'" href="'+$('StoryALink').value+'" '+linkTarget+'>'+spEditor.selection['inside']+'</a>'+spEditor.selection['after'];
    }
    spEditor.clearSelection();
  },
  
  increaseFontSize:function(){
    if( this.activeComponent != null ) {;
      this.activeComponent.increaseFontSize();
    }
  },
  
  decreaseFontSize:function(){
    if( this.activeComponent != null ) {;
      this.activeComponent.decreaseFontSize();
    }
  },
  
  setColor:function( c ){
    if( this.activeComponent != null ) {;
      this.activeComponent.setColor( c );
    }
  },

  setAlign:function( a ){
    if( this.activeComponent != null ) {;
      this.activeComponent.setAlign( a );
    }
  },
  
  setSpan:function( s ){
    if( this.activeComponent != null ) {;
      this.activeComponent.setSpan( s );
    }
  },
  
  toggleEdit:function(){
    if( this.activeComponent != null ) {;
      if( this.activeComponent.edit ){
        this.unedit();
      } else {
        this.edit();
      }
    }
  },
  
  edit:function(){
    this.editorP.className = this.activeComponent.e.className;
    this.editorP.value = this.activeComponent.getText();
    this.activeComponent.e.insert({ after: this.editorP });
    
    this.activeComponent.e.hide();
    this.activeComponent.edit = true;
  },
  
  unedit:function(){
    this.activeComponent.setText( this.editorP.value );
    
    this.editorP.remove();
    this.activeComponent.e.show();
    this.activeComponent.edit = false;

  },

  remove:function(){
    var oac = this.deactivate();
    
    if( oac != null ) {
      var olds = this.components;
      var news = [];
      
      for( var i=0,l=olds.length; i<l; i++ ){
        var old = olds[i];
        if( old != oac ){
          news[ news.length ] = old;
        }
      }
    
      this.components = news;
      
      oac.e.remove();
    }
  },
  
  showHTML:function(){
    alert( this.toHTML() );
  },
  
  toHTML:function(){
    var cmpnts = this.components;
    var h = '';
    h += '<div>';
    
    for( var i=0,l=cmpnts.length; i<l; i++ ){
      h += cmpnts[i].toHTML();
    }
    
    h += '</div>';
    
    return h;
  },
  
  saveTo:function( e ){
    this.deactivate();
    
    //alert( e.value );
    //alert( '<div>' + ( this.content.innerHTML ).strip() + '</div>' );
    e.value = this.toHTML();
    //alert( e.value );
    return true;
  },
  
  deactivate:function(){
    if( this.activeComponent != null ){
      if( this.activeComponent.edit ){
        this.unedit();
      }
      
      this.editBar.hide();
      this.activeComponent.deactivate();
      var oac = this.activeComponent;
      this.activeComponent = null;
      
      return oac;
    }
    
    return null;
  },
  
  getNextId:function(){
    return 'sp_cmpnt_' + this.nextId++;
  }
});



StoryComponent = Class.create({
  initialize:function( id, obj ){
    this.e = null;
    this.id = id;
    this.active = false;
    this.listeners = [];
    this.edit = false;
    
    if( Object.isElement( obj ) ){
      this.loadElement( obj );
    } else {
      this.createElement( obj );
    }
    
    this.bindEventHandlers();
  },
  
  getElement:function(){
    return this.e;
  },
  
  addListener:function( l ){
    this.listeners[ this.listeners.length ] = l;
  },
  
  loadElement:function( obj ){
    this.e = obj;
    this.e.id = this.id;
  },
  
  createElement:function( obj ){
    var type = obj.type;
    this.e = new Element( type, { 'id':this.id } );
    this.e.className = obj.css;
  },
  
  getCSSValue:function( key ){
    return this.getCSS().get( key );
  },
  
  setCSSValue:function( key, value ){
    var css = this.getCSS();
    css.set( key, value );
    this.setCSS( css );
  },
  
  getCSS:function(){
    var cns = $w( this.e.className );
    var css = new Hash();
    for( var i=0,l=cns.length; i<l; i++ ){
      var kv = cns[i].split( '-' );
      if( kv[1] ){
        css.set( kv[0], kv[1] );
      }
    }
    
    return css;
  },
  
  setCSS:function( css ){
    var cn = '';
    var s = css.size();
    css.each( function( kv, i ){ cn += ( kv.key + '-' + kv.value ); if( i < (s-1) ) { cn += ' ' }; } );
    this.e.className = cn;
    
    if( this.active ){
      this.e.addClassName( 'active' );
    }
  },
  
  bindEventHandlers:function(){
    Event.observe( this.e, 'click', this.processClick.bindAsEventListener( this ) );
  },
  
  processClick:function(){
    this.fireClick();
  },
  
  fireClick:function(){
    var ls = this.listeners;
    for( var i=0, l=ls.length; i<l; i++ ){
      ls[i].storyComponentClicked( this );
    }
  },
  
  activate:function(){
    this.active = true;
    this.e.addClassName( 'active' );
  },
  
  deactivate:function(){
    this.active = false;
    this.e.removeClassName( 'active' );
  },
  
  increaseFontSize:function(){
    var s = parseInt( this.getCSSValue( 's' ) );
    if( s < 5 ){
      this.setCSSValue( 's', ++s )
    }
  },
  
  decreaseFontSize:function(){
    var s = parseInt( this.getCSSValue( 's' ) );
    if( s > 1 ){
      this.setCSSValue( 's', --s )
    }
  },
  
  setColor:function( c ){        
    this.setCSSValue( 'c', c )
  },
  
  setAlign:function( a ){        
    this.setCSSValue( 'a', a )
  },
  
  setSpan:function( cs ){        
    this.setCSSValue( 'cs', cs )
  }
  
});



StoryP = Class.create( StoryComponent, {
  initialize:function( $super, id, obj ){
    
    if( !( obj ) ){
      obj = { 'type':'P', 'css':'c-slate s-3' };
    } else if( !( Object.isElement( obj ) ) ) {
      alert( 'elm = ' + Object.isElement( obj ) );
      obj[ 'type' ] = 'P';
    }
    
    $super( id, obj );
  },
  
  setText:function( t ){
    this.e.innerHTML = t.gsub( '\n', '<br />' );
  },
  
  getText:function( t ){
    return this.e.innerHTML.gsub( '<br />', '\n' ).gsub( '<br>', '\n' ).gsub( '<x>', '' ).gsub( '</x>', '' );
  },
  
  toHTML:function(){
    return '<p class="' + this.e.className + '">' + this.e.innerHTML.gsub( '<br>', '<br />' ) + '</p>';
  }
  
});


StoryOL = Class.create( StoryComponent, {
  initialize:function( $super, id, obj ){
    if( !( obj ) ){
      obj = { 'type':'OL', 'css':'c-slate s-3' };
    } else if( !( Object.isElement( obj ) ) ) {
      alert( 'elm = ' + Object.isElement( obj ) );
      obj[ 'type' ] = 'OL';
    }
    
    $super( id, obj );
  },
  
  setText:function( t ){
    var items = t.split( '\n' );
    t = ''
    
    for( var i=0, l=items.length; i<l; i++ ){
      if( items[i] != '' ){
        t += '<li>' + items[i] + '<\/li>';
      }
    }
    
    this.e.innerHTML = t;
  },
  
  getText:function( t ){
    return this.e.innerHTML.gsub( '<li>', '' ).gsub( '<\/li>', '\n' ).gsub( '<x>', '' ).gsub( '</x>', '' );
  },
  
  toHTML:function(){
  
    //var lis = this.e.childElements();
    var h = '';
    h += '<ol class="' + this.e.className + '">';
    h += this.e.innerHTML;
    h += '</ol>';
    
    return h;
  }
});


StoryUL = Class.create( StoryComponent, {
  initialize:function( $super, id, obj ){
    if( !( obj ) ){
      obj = { 'type':'UL', 'css':'c-slate s-3' };
    } else if( !( Object.isElement( obj ) ) ) {
      alert( 'elm = ' + Object.isElement( obj ) );
      obj[ 'type' ] = 'UL';
    }
    
    $super( id, obj );
  },
  
  setText:function( t ){
    var items = t.split( '\n' );
    t = ''
    
    for( var i=0, l=items.length; i<l; i++ ){
      if( items[i] != '' ){
        t += '<li>' + items[i] + '<\/li>';
      }
    }
    
    this.e.innerHTML = t;
  },
  
  getText:function( t ){
    return this.e.innerHTML.gsub( '<li>', '' ).gsub( '<\/li>', '\n' ).gsub( '<x>', '' ).gsub( '</x>', '' );
  },
  
  toHTML:function(){
  
    //var lis = this.e.childElements();
    var h = '';
    h += '<ul class="' + this.e.className + '">';
    h += this.e.innerHTML;
    h += '</ul>';
    
    return h;
  }
});

StoryIMG = Class.create( StoryComponent, {
  initialize:function( $super, id, obj ){
    
    if( !( obj ) ){
      alert( 'StoryImage.initialize: no obj' );
    } else if( !( Object.isElement( obj ) ) ) {
      obj[ 'type' ] = 'DIV';
      obj[ 'css' ] = 't-img cs-6 a-c c-slate';
    }
    
    
    this.imageId;
    this.rootFilename;
    this.ext;
    this.img;
    this.p;
    $super( id, obj );
  },

  loadElement:function( $super, obj ){
    $super( obj );
    
    this.img = obj.getElementsBySelector( 'img' )[0];
    this.p = obj.getElementsBySelector( 'p' )[0];
    
    // Absolute URIs should not be parsed
    if( this.img.src.indexOf('http://') == 0 || this.img.src.indexOf('https://') == 0 ) {
      this.imageId = this.img.id;
      this.rootFilename = this.img.src;
    } else {
      
      var split1 = this.img.src.split( '/' );
      var fileName = split1.last();
      var split2 = fileName.split( '.' );
      var split3 = split2.first().split( '_' );
    
      split3.pop();
    
      this.imageId = this.img.id
      this.rootFilename = split3.join( '_' );
      this.ext = split2.last();
    }
  },
  
  createElement:function( $super, obj ){
    $super( obj );
    
    this.imageId = obj.asset_id;
    this.rootFilename = obj.root_filename;
    this.ext = obj.extension;
    
    this.img = new Element( 'img', { 'id':this.rootFilename, 'src':this.getFileName() } );
    this.e.insert( this.img );
    
    if( obj.description != '' ){
      this.p = new Element( 'p' );
      this.p.insert( obj.description );
    }
    
    this.e.insert( this.p );
  },
  
  getFileName:function(){
    // Avoid parsing if it's an absolute URI.
    if( this.rootFilename.indexOf('http://') == 0 || this.rootFilename.indexOf('https://') == 0 ) {
      return this.rootFilename;
    } else {
      return '/uploads/images/' + this.rootFilename + '_' + this.getCSSValue( 'cs' ) + '.' + this.ext;
    }
  },
  
  setText:function( t ){
    var items = t.split( '\n' );
    t = ''
    
    for( var i=0, l=items.length; i<l; i++ ){
      if( items[i] != '' ){
        t += '<li>' + items[i] + '<\/li>';
      }
    }
    
    this.e.innerHTML = t;
  },
  
  getText:function( t ){
    return this.e.innerHTML.gsub( '<li>', '' ).gsub( '<\/li>', '\n' );
  },
  
  setAlign:function( $super, a ){        
    $super( a );
    
    if( a == 'l' || a == 'r' ){
      if( this.getCSSValue( 'cs' ) > 2 ){
        this.setSpan( 2 );
      }
    } else {
      this.setSpan( 6 );
    }
  },
  
  setSpan:function( $super, cs ){        
    $super( cs );

    this.img.src = this.getFileName();
  },
  
  toHTML:function(){
    var h = '';
    h += '<div class="' + this.e.className + '">';
    h += '<img id="' + this.imageId + '" src="' + this.getFileName() + '" />';
    
    if( this.p ){
    h += '<p>' + this.p.innerHTML + '</p>';
    }
    h += '</div>';
    
    return h;
  }
});
