
var json = JSON;

dojo.require("dojo.string.*");
dojo.require("dojo.html.*");
dojo.require("dojo.style.*");
dojo.require("dojo.io.cookie.*");


var gFadeOut_final     = 0.9;
var gFadeOut_step      = 0.01;
var gFadeOut_steptime  = 250;

var gNextFadeOut = function( node, opacity, obj ) {
  if( gFadeOut_final < opacity && obj.expanded ) {
    dojo.style.setOpacity(node,opacity);
    dojo.lang.setTimeout( this, 'gNextFadeOut', gFadeOut_steptime, node, opacity-gFadeOut_step, obj );
  } 
}


function $(id) {
  return document.getElementById(id);
}

function $attr(node,attr) {
  return node.getAttribute(attr);
}

function Tagger( form ) {
  var self = this;

  self.form = form;
  self.elem = {
    more: $('more'),
    topadbar: $('topadbar')
  };
  self.expanded = false;

  var sepchar = { comma:',', space:' ' };
  var tm      = null;

  var editsite = null;

  var selectedsites = {};
  for( var sI in tm ) {
    selectedsites[sI] = false;
  }

  // test comma: a,"b","c,d","e""f",&,<b>g</b>,h+i,j k
  // test space: a "b" "c d" "e""f" & <b>g</b> h+i j,k
  var csv_suffix      = '(?=(?:[^"]*"[^"]*")*(?![^"]*"))';
  var re_csv_comma    = new RegExp( '\\s*,+\\s*'+csv_suffix );
  var re_csv_space    = new RegExp( ' +'+csv_suffix );
  var re_doubledollar = new RegExp( '\\$\\$', 'g' );

  var targetcode = {'_top':'t','_blank':'b','_self':'s','_parent':'p'};
  for( var v in targetcode ) {
    if( 1 < v.length ) {
      targetcode[targetcode[v]] = v;
    }
  }

  var sepcode = { 'comma':'c', 'space':'s' };
  for( var v in sepcode ) {
    if( 1 < v.length ) {
      sepcode[sepcode[v]] = v;
    }
  }

  var insert = function( tm, values ) {
    for( var valname in values ) {
      tm = tm.replace( new RegExp('\\$'+valname,"g"), values[valname] );
    }
    tm = tm.replace( re_doubledollar, '$' );
    return tm;
  }

  var makeTextTags = function( tags ) {
    var texttags = [];
    for( var tI = 0; tI < tags.length; tI++ ) {
      var texttag = tags[tI];
      texttags[tI] = dojo.string.escapeXml(texttag);
    }
    return texttags;
  }

  var makeUrlTags = function( tags ) {
    var urltags = [];
    for( var tI = 0; tI < tags.length; tI++ ) {
      var urltag = tags[tI];
      urltags[tI] = dojo.string.encodeAscii(urltag);
      urltags[tI] = urltags[tI].replace(/%20/g,'+');
    }
    return urltags;
  }

  var getRadioValue = function( radio ) {
    var value = null;
    for( var rI = 0; rI < radio.length; rI++ ) {
      if( radio[rI].checked ) {
         value = radio[rI].value;
         break;
      }
    }
    return value;
  }


  self.buildtags = function( tags, values ) {
    var texttags  = makeTextTags( tags );
    var urltags   = makeUrlTags( tags );

    var outb = [];

    for( var site in tm ) {
      if( selectedsites[site] ) {
        var tmparts = tm[site];
        outb.push( tmparts.prefix );
        for( var tI = 0; tI < texttags.length; tI++ ) {
          values.texttag = texttags[tI];
          values.urltag = urltags[tI];
          outb.push( insert( tmparts.body, values ) );
        }
        outb.push( tmparts.suffix );
      }
    }
    return outb.join('');
  }


  self.parsetags = function( sep, tagsin ) {
    var intags = tagsin.split( 'comma'==sep?re_csv_comma:re_csv_space );
    var tags   = [];
    for( var tI = 0; tI < intags.length; tI++ ) {
      var tag = intags[tI];
      if( 2 < tag.length ) {
        if( '"' == tag[0] && '"' == tag[tag.length-1] ) {
          tag = tag.substring(1,tag.length-1);
        }
      }
      if( 0 < tag.length ) {
        tag = tag.replace(/\+/g,' ');
        tags.push(tag);
      }
    }
    return tags;
  }


  self.keypressOnTags = function( evt ) {
    if( dojo.event.browser.keys.KEY_ENTER == evt.keyCode ) {
      self.generate();
    }
  }


  self.generate = function() {
    var tagstr = self.form.tags.value;
    if( 0 == tagstr.length ) {
      alert('Please enter some tags.');
    }
    else {
      var tags     = self.parsetags(getRadioValue(self.form.sep),tagstr);
      var target   = getRadioValue(self.form.target);
      var relation = self.form.relation.value;
      var tagsoup  = self.buildtags(tags, {target:target,relation:relation});
      self.form.out.value = tagsoup;
      $('tagsoup').innerHTML = tagsoup;
    }
  }

  self.selectsite = function( arg ) {
    var site = null;
    if( dojo.lang.isString( arg ) ) {
      site = arg;
    }
    else {
      site = arg.currentTarget.value;
    }
    selectedsites[site] = $( 'c_site_'+site ).checked;
  }

  self.selecthtml = function() {
    self.form.out.focus(); 
    self.form.out.select(); 
  }

  self.editsite = function( arg ) {
    if( editsite ) {
      $('a_site_'+editsite).fontWeight = 'normal';
      $('r_site_'+editsite).checked = false;
    }
    var site = null;
    if( dojo.lang.isString( arg ) ) {
      site = arg;
    }
    else {
      site = arg.currentTarget.getAttribute('value');
    }
    editsite = site;
    var tmparts = tm[editsite];
    self.form.prefix.value = tmparts.prefix;
    self.form.body.value = tmparts.body;
    self.form.suffix.value = tmparts.suffix;
    $('a_site_'+editsite).fontWeight = 'bold';
    $('r_site_'+editsite).checked = true;
  }

  self.updatetm = function() {
    var tmparts = tm[editsite];
    tmparts.prefix = self.form.prefix.value;
    tmparts.body   = self.form.body.value;
    tmparts.suffix = self.form.suffix.value;
  }

  self.showOptions = function( pev ) {
    showInfo( self.elem.more );
  }

  var showInfo = function( infonode ) {
    var x = dojo.style.getAbsoluteX(self.elem.topadbar);
    var y = dojo.style.getAbsoluteY(self.elem.topadbar);
    infonode.style.left = (x+5)+'px';
    infonode.style.top  = (y+5)+'px';
    dojo.html.show( infonode );
    self.expanded = true;
    gNextFadeOut( infonode, 1.0, self );
  }

  self.saveAndClose = function( pev ) {
    self.expanded = false;
    self.hideOptions();

    var data = makeData();
    var d=new Date();
    d.setTime(d.getTime()+(5*365*24*60*60*1000));
    document.cookie = "soctag="+data+"; expires="+d.toGMTString()+";";
  }

  
  self.hideOptions = function() {
    dojo.html.hide( self.elem.more );
  }


  self.resetOptions = function() {
    tm = 
    { technorati:
      { prefix:'<span class="technoratitag">Technorati Tags: ',
        body:'<a href="http://www.technorati.com/tag/$urltag" target="$target" rel="$relation" title="Technorati tag: $texttag">$texttag</a> ',
        suffix:'</span>' },
      delicious:
      { prefix:'<span class="delicioustag">Del.icio.us Tags: ',
        body:'<a href="http://del.icio.us/tag/$urltag" target="$target" rel="$relation" title="Del.icio.us tag: $texttag">$texttag</a> ',
        suffix:'</span>' },
      flickr:
      { prefix:'<span class="flickrtag">Flickr Tags: ',
        body:'<a href="http://www.flickr.com/photos/tags/$urltag" target="$target" rel="$relation" title="Flickr tag: $texttag">$texttag</a> ',
        suffix:'</span>' },
      furl:
      { prefix:'<span class="furltag">Furl Tags: ',
        body:'<a href="http://www.furl.net/furled.jsp?topic=$urltag" target="$target" rel="$relation" title="Furl tag: $texttag">$texttag</a> ',
        suffix:'</span>' }
    };

    $( 'c_site_technorati' ).checked = true; 
    self.selectsite('technorati');

    self.editsite('technorati');

    $('r_sep_space').checked = true;
    $('r_tar_top').checked = true;
    self.form.relation.value = 'tag';
  }

  var makeData = function() {
    return '01' + 
      (self.form.site_tech.checked?'y':'n') +
      (self.form.site_deli.checked?'y':'n') +
      (self.form.site_flkr.checked?'y':'n') +
      (self.form.site_furl.checked?'y':'n') +
      escape(sepcode[getRadioValue(self.form.sep)]+
             targetcode[getRadioValue(self.form.target)]+
             self.form.relation.value) + '&' +
      escape(tm.technorati.prefix+'|'+tm.technorati.body+'|'+tm.technorati.suffix+'|'+
             tm.delicious.prefix+'|'+tm.delicious.body+'|'+tm.delicious.suffix+'|'+
             tm.flickr.prefix+'|'+tm.flickr.body+'|'+tm.flickr.suffix+'|'+
             tm.furl.prefix+'|'+tm.furl.body+'|'+tm.furl.suffix);
  }

  var parseData = function( text ) {
    var parts = text.split('&');

    var settings = unescape(parts[0]);
    var tmitems = unescape(parts[1]).split('|');
    for( var i = 0; i < tmitems.length; i++ ) {
      tmitems[i] = unescape(tmitems[i]);
    }
    
    var data = 
     { version:sepcode[settings.substring(0,2)], 
       sites:{ tech:settings.substring(2,3),
               deli:settings.substring(3,4),
               flkr:settings.substring(4,5),
               furl:settings.substring(5,6) },
       sep:sepcode[settings.substring(6,7)], 
       target:targetcode[settings.substring(7,8)],
       rel:settings.substring(8),
       tm:{technorati:{prefix:tmitems[0],body:tmitems[1],suffix:tmitems[2]},
	   delicious:{prefix:tmitems[3],body:tmitems[4],suffix:tmitems[5]},
           flickr:{prefix:tmitems[6],body:tmitems[7],suffix:tmitems[8]},
  	   furl:{prefix:tmitems[9],body:tmitems[10],suffix:tmitems[11]} } };

    return data;
  }

  self.loadSettings = function( text ) {
    try {
      var data = parseData( text );
      $('r_sep_'+data.sep).checked = true;
      $('r_tar'+data.target).checked = true;
      self.form.relation.value = data.rel;

      if( 'y'==data.sites.tech ) { 
        $( 'c_site_technorati' ).checked = true; 
        self.selectsite('technorati'); 
      }

      if( 'y'==data.sites.deli ) { 
        $( 'c_site_delicious' ).checked = true; 
        self.selectsite('delicious');
      }

      if( 'y'==data.sites.flkr ) { 
        $( 'c_site_flickr' ).checked = true; 
        self.selectsite('flickr');
      }

      if( 'y'==data.sites.furl ) { 
        $( 'c_site_furl' ).checked = true; 
        self.selectsite('furl');
      }

      tm = data.tm;           	
    }
    catch( e ) {
      alert( 'Previous settings stored in cookie were incorrectly formatted, reverting to defaults: '+e );
      self.resetOptions();
    }
  }


  self.showInfoPage = function( pev ) {
    var showpage = pev.currentTarget.getAttribute('page');
    dojo.lang.forEach( ['comment','tags','credits'], 
      function( pn ) { if( pn != showpage ) { self.hideInfoPage(null,pn); } }  )
    showInfo( $( showpage+'info' ) );
  }

  self.hideInfoPage = function( pev, pagename ) {
    if( null == pagename ) {
      pagename = pev.currentTarget.getAttribute('page');
    }
    dojo.html.hide( $( pagename+'info' ) );
  }

  self.submitComment = function() {
    var data = { 
      name:$('comment_name').value,
      email:$('comment_email').value,
      site:$('comment_site').value,
      text:$('comment_text').value
    };

   self.setMessage( "Submitting comment..." );

   dojo.io.bind({
      url: 'tags.jsp',
      method: 'post',
      postContent: json.stringify(data),
      handle: function(type, data, evt){
        if( type == 'load' ){
          self.setMessage( "Thanks for your comment!" );
        }
        else {
          self.setMessage( "Sorry, there's been a server error. Just send me an email." );
        }
      },
      mimetype: 'text/plain'
    });
  }

  self.setMessage = function( msg ) {
    alert( msg );
  }
}


function init() {
  var tagger = new Tagger( document.tags );

  $( 'c_site_technorati' ).checked = false; 
  $( 'c_site_delicious' ).checked = false; 
  $( 'c_site_flickr' ).checked = false; 
  $( 'c_site_furl' ).checked = false; 

  var idx = document.cookie.indexOf('soctag'+'=');
  if(idx != -1) { 
    var value = document.cookie.substring(idx+6+1);
    var end = value.indexOf(';');
    if(end == -1) { end = value.length; }
    value = value.substring(0, end);
    tagger.loadSettings( value );
  }
  else {
    tagger.resetOptions();
  }

  tagger.editsite('technorati');

  dojo.event.connect( $('b_gen'), 'onclick', tagger, 'generate' );
  dojo.event.connect( $('b_mor'), 'onclick', tagger, 'showOptions' );
  dojo.event.connect( $('b_sav'), 'onclick', tagger, 'saveAndClose' );
  dojo.event.connect( $('b_cls'), 'onclick', tagger, 'hideOptions' );
  dojo.event.connect( $('b_rst'), 'onclick', tagger, 'resetOptions' );

  dojo.event.connect( $('t_tags'), 'onkeypress', tagger, 'keypressOnTags' );

  dojo.event.connect( $('a_tags'),       'onclick', tagger, 'showInfoPage' );
  dojo.event.connect( $('a_tags_close'), 'onclick', tagger, 'hideInfoPage' );

  dojo.event.connect( $('a_comment'),       'onclick', tagger, 'showInfoPage' );
  dojo.event.connect( $('b_comment_close'), 'onclick', tagger, 'hideInfoPage' );
  dojo.event.connect( $('b_comment_submit'), 'onclick', tagger, 'submitComment' );

  dojo.event.connect( $('a_credits'),       'onclick', tagger, 'showInfoPage' );
  dojo.event.connect( $('a_credits_close'), 'onclick', tagger, 'hideInfoPage' );


  dojo.event.connect( $('c_site_technorati'), 'onclick', tagger, 'selectsite' );
  dojo.event.connect( $('c_site_delicious'), 'onclick', tagger, 'selectsite' );
  dojo.event.connect( $('c_site_flickr'), 'onclick', tagger, 'selectsite' );
  dojo.event.connect( $('c_site_furl'), 'onclick', tagger, 'selectsite' );

  dojo.event.connect( $('a_site_technorati'), 'onclick', tagger, 'editsite' );
  dojo.event.connect( $('a_site_delicious'), 'onclick', tagger, 'editsite' );
  dojo.event.connect( $('a_site_flickr'), 'onclick', tagger, 'editsite' );
  dojo.event.connect( $('a_site_furl'), 'onclick', tagger, 'editsite' );

  dojo.event.connect( $('r_site_technorati'), 'onclick', tagger, 'editsite' );
  dojo.event.connect( $('r_site_delicious'), 'onclick', tagger, 'editsite' );
  dojo.event.connect( $('r_site_flickr'), 'onclick', tagger, 'editsite' );
  dojo.event.connect( $('r_site_furl'), 'onclick', tagger, 'editsite' );


  dojo.event.connect( tagger.form.out, 'onclick', tagger, 'selecthtml' );

  dojo.event.connect( $('t_pre'), 'onchange', tagger, 'updatetm' );
  dojo.event.connect( $('t_bod'), 'onchange', tagger, 'updatetm' );
  dojo.event.connect( $('t_suf'), 'onchange', tagger, 'updatetm' );
}
