
$(document).ready( function()
{
  Wishlist.init(
  {
    page:      parseInt( $( "#page" ).val() ),
    boxcount:  10,
    votesleft: parseInt( $( "#span_yourvotes" ).html() )
  });
});

/*
 *
 * Wishlist object
 *
 */

var Wishlist = {
  /*
   * Attributes
   */
  page: 1,
  boxcount: 2,
  votesleft: 0,
  displayingSearchResult: false,
  resultPage: 1,
  debugging: false,
  articlesVoted: [],
  currentlyRunningAsins: [],

  /*
   * Initialisation of object attributes
   */
  init: function( params )
  {
    if ( typeof ( params ) != "undefined" )
    {
      if ( typeof ( params.page )      != "undefined" ) this.page      = params.page;
      if ( typeof ( params.boxcount )  != "undefined" ) this.boxcount  = params.boxcount;
      if ( typeof ( params.votesleft ) != "undefined" ) this.votesleft = params.votesleft;
    }
    $( ".running_auction_asin" ).each( function()
    {
      Wishlist.currentlyRunningAsins.push( $( this ).val() );
    });
    if ( this.debugging )
    {
      // debug window
      var debugWindow = $( '<textarea id="textarea_debug" cols="42" rows="30" style="z-index:399;"></textarea>' );
      debugWindow.css( "position", "absolute" );
      debugWindow.css( "top", "150px" );
      debugWindow.css( "left", "0" );
      $( "body" ).append( debugWindow );
    }
  },

  /*
   * Public method setResult
   *
   * expects array of data objects
   */
  setResult: function( resultSets, page )
  {
    $( "#div_toplist" ).hide();
    $( "#div_toplistpaging" ).hide();
    $( "#div_searchresult_content" ).show();
    $( "#div_searchresult_paging" ).show();
    $( "#div_searchresult" ).css( "height", "546px" );
    this.resultPage = 1;
    this.displaySearchResult( true );
    // empty result div and create box divs for elements
    $( "#div_searchresult_content" ).html( "" );
    if ( resultSets.length == 0 )
    {
      $( "#div_searchresult_content" ).html( "Deine Suche lieferte keine Ergebnisse. Probiere es mit Suchen in einer anderen Produktkategorie." );
    }
    else
    {
      if ( resultSets.length >= 10 ) $( "#a_livesearchpaginator_next" ).show();
      else $( "#a_livesearchpaginator_next" ).hide();
      if ( page > 1 ) $( "#a_livesearchpaginator_prev" ).show();
      else $( "#a_livesearchpaginator_prev" ).hide();
      var c, it = 0;
      var boxes = $( "#div_toplist" ).find( ".article-box" );
      var toClone = $( boxes[it] );
      do
      {
        toClone = $( boxes[it] );
        c = toClone.egrep( "nicht verfügbar" );
        it++;
      }
      while ( c.length > 0 );
      toClone.find( ".article-image" );
      var artImg = $( c[0] );
      artImg.attr( "src", "/images/page-bg.png" );
      for ( var it = 0 ; it < resultSets.length ; it++ )
      {
        var dataset = resultSets[it];
        dataset.blacklisted = false;
        var boxDiv = this.createArticleMarkup( resultSets[it], toClone );
        $( "#div_searchresult_content" ).append( boxDiv );
      }
    }
    $( ".a_placevote_searchresult" ).each( function()
    {
      $( this ).click( function() { wish( getId( $( this ).attr( "id" ) ) ) });
    });
    $( ".button_login" ).each( function()
    {
      $( this ).click( function() { toggleLogin(); } )
    });
  },

  /*
   * Public method updateResultBoxDiv
   *
   * expects object with article data
   */
  updateResultBoxDiv: function( data )
  {
    $( "#div_rank_" + data.asin ).html( "" + data.rank + ". Platz" );
    var boxDiv = $( "#div_box_" + data.asin );
    this.animate( boxDiv );
    var alreadyStored = false;
    for ( var it in this.articlesVoted )
    {
      var asin = this.articlesVoted[it];
      if ( asin == data.asin ) alreadyStored = true;
      else update( asin );
    }
    if ( !alreadyStored ) this.articlesVoted.push( data.asin );
  },
  updateResultBoxDivSilently: function( data )
  {
    $( "#div_rank_" + data.asin ).html( "" + data.rank + ". Platz" );
  },

  /*
   * Private method animate
   *
   * expects jquery DOM element object
   * highlights the user action
   */
  animate: function( boxElement )
  {
    boxElement.css( "opacity", "0" );
    var c = boxElement.find( ".image" );
    var div = $( c[0] );
    div.css( "border", "1px solid green" );
    //boxElement.animate( { opacity: 1 }, 1000 );
  },

  /*
   * Private method incrementRank
   *
   * expects jquery DOM element object
   * increments the rank in the markup it's pointed to
   */
  incrementRank: function( boxElement )
  {
    // get current rank
    var asin = getId( boxElement.attr( "id" ) );
    // get rank element from box
    var rank = this.parseRank( $( "#div_rank_" + asin ).html() );
    rank++;
    // set new rank
    $( "#div_rank_" + asin ).html( "" + rank + ". Platz" );
  },
  incrementRankViaAsin: function( asin )
  {
    var rank = this.parseRank( $( "#div_rank_" + asin ).html() ) + 1;
    $( "#div_rank_" + asin ).html( "" + rank + ". Platz" );
  },

  /*
   * Private method decrementRank
   *
   * expects jquery DOM element object
   * decrements the rank in the markup it's pointed to
   */
  decrementRank: function( boxElement )
  {
    // get current rank
    var asin = getId( boxElement.attr( "id" ) );
    // get rank element from box
    var rank = this.parseRank( $( "#div_rank_" + asin ).html() );
    //debug( "decrementRank: old rank was " + rank + ", first rank on current page is " + this.getFirstDisplayedRank() );
    if ( rank >= this.getFirstDisplayedRank() )
    {
      rank--;
      // decrease & set rank
      $( "#div_rank_" + asin ).html( "" + rank + ". Platz" );
    }
    //debug( "decrementRank: " + asin + " auf " + rank + ". Platz" );
  },
  setRank: function( obj )
  {
    $( "#div_rank_" + obj.asin ).html( "" + obj.rank + ". Platz" );
  },

  scaleImageSrc: function( str )
  {
    str = "" + str;
    var scaleToPx = 120;
    var needle = "._SL";
    var pos = str.lastIndexOf( needle );
    if ( pos > -1 )
    {
      var start = str.substring( 0, pos + needle.length )
      var end   = str.substring( pos + needle.length );
      needle = "_.";
      pos = end.lastIndexOf( needle );
      end = end.substring( pos );
      str = start + scaleToPx + end;
    }
    return str;
  },

  createArticleMarkup: function( obj, toClone )
  {
    var boxDiv = toClone.clone();
    var c = boxDiv.find( "a" );
    var voteLink = $( c[1] );
    var c = boxDiv.find( ".orangebutton" );
    var voteLinkTag = $( c[0] );
    //
    var elId = this.replaceAsin( boxDiv.attr( "id" ), obj.asin );
    boxDiv.attr( "id", elId );
    boxDiv.addClass( "div_jspaginated" );
    // rank div
    var c = boxDiv.find( ".rank-div" );
    var rankDiv = $( c[0] );
    // image
    c = boxDiv.find( ".article-image" );
    var artImg = $( c[0] );
    // image div
    c = boxDiv.find( ".image" );
    var imageTag = $( c[0] );
    // image link
    c = boxDiv.find( ".imagelink" );
    var imageLinkTag = $( c[0] );
    // title
    c = boxDiv.find( ".title" );
    var titleTag = $( c[0] );
    // link href
    var href = "http://www.amazon.de/gp/product/" + obj.asin + "?tag=xgewinnt-21";

    artImg.attr( "src", this.scaleImageSrc( obj.imgsrc ) );
    artImg.attr( "alt", obj.title );
    imageTag.css( "border", "1px solid #ccc" );
    elId = this.replaceAsin( rankDiv.attr( "id" ), obj.asin );
    rankDiv.attr( "id", elId );
    voteLinkTag.removeClass( "button_login" );
    imageLinkTag.attr( "href", href );
    imageLinkTag.attr( "target", "_new" );
    imageLinkTag.attr( "name", "evtst|a|"+obj.asin );
    var isRunningAsin = false;
    for ( var index in this.currentlyRunningAsins )
    {
      if ( this.currentlyRunningAsins[index] == obj.asin )
      {
        isRunningAsin = true;
        break;
      }
    }
    if ( obj.totalOffers == 0 )
    {
      rankDiv.html( "&nbsp;" );
      imageLinkTag.attr( "title", "Der Versand durch Amazon.de ist derzeit nicht verfügbar" );
      imageLinkTag.removeAttr( "id" );
      voteLinkTag.replaceWith( '<span style="font-size: smaller;">Der Versand durch Amazon.de ist derzeit nicht verfügbar.</span>' );
    }
    else if ( isRunningAsin )
    {
      rankDiv.html( "Wunschartikel" );
      voteLink.css( 'height', '29px' );
      var href = "/wunschartikel/" + obj.asin;
      var fc = this.hasFrontController( window.location.href );
      if ( fc ) href = fc + href;
      voteLinkTag.attr( "href", href );
      voteLinkTag.html( '' );
      voteLinkTag.attr( "title", "Mitmachen" );
      voteLinkTag.removeClass("button_login");
      voteLinkTag.addClass( "orangebutton" );
      var outerButtonDiv = $( '<div class="orangebutton-outer" style="width: 140px;">' );
      outerButtonDiv.append( '<div class="orangebutton-inner"></div>' );
      outerButtonDiv.append( 'zum Wunschartikel' );
      voteLinkTag.append( outerButtonDiv );
    }
    else
    {
      rankDiv.html( "&nbsp;" );
      voteLink.attr( "id", elId );
      var href = "/wunsch/" + obj.asin;
      var fc = this.hasFrontController( window.location.href );
      if ( fc ) href = fc + href;
      voteLinkTag.attr( "href", href );
    }
    titleTag.html( "" );
    var a = $( '<a rel="nofollow" target="_blank" class="previewlink" href="http://www.amazon.de/gp/product/' + obj.asin + '?tag=xgewinnt-21"></a>' );
    var d = $( '<div class="amzico"></div>' );
    a.append( d );
    titleTag.append( a );
    titleTag.append( '<span>' + obj.title + '</span>' );
    return boxDiv;
  },

  hasFrontController: function( href )
  {
    var match = href.match( /\/frontend_(.*).php/ );
    if ( match ) return match[0];
    return false;
  },

  replaceAsin: function( str, asin )
  {
    if ( str )
    {
      var pos = str.lastIndexOf( "_" );
      return str.substring( 0, pos +1 ) + asin;
    }
    return "";
  },

  /*
   * Public method moveArticle
   *
   * expects object with article data
   */
  moveArticle: function( data )
  {
    //debug( data.asin + ": " + data.votes + " Votes, new rank: " + data.rank + " (" + data.title + ")" );
    var voted_div = $( "#div_box_" + data.asin );
    var sibling = voted_div.prev();
    var divs = [];
    while ( typeof ( sibling.attr( "id" ) ) != "undefined" )
    {
      divs.push( sibling );
      if( this.parseRankFromBoxDiv( sibling ) == data.rank )
      {
        voted_div.remove();
        voted_div.insertBefore( sibling );
        this.setRank( data );
        for ( var it in divs )
        {
          var asin = getId( divs[it].attr( "id" ) );
          update( asin );
          divs[it].remove();
          //this.incrementRank( divs[it] );
        }
        divs = this.sortDivsByRank( divs );
        for ( var it in divs )
        {
          var c = divs[it].find( ".a_placevote" );
          $( c[0] ).click( function()
          {
            var asin = getId( $( this ).attr( "id" ) );
            wish( asin );
          });
          divs[it].insertAfter( voted_div );
        }
        //var c = voted_div.find( ".a_placevote" );
        //var a = $( c[0] );
        //a.click( function() { wish( getId( $( this ).attr( "id" ) ) ) } );
        break;
      }
      sibling = sibling.prev();
    }
    voted_div.css( "opacity", "0" );
    var c = voted_div.find( ".image" );
    var div = $( c[0] );
    div.css( "border", "1px solid orange" );
    voted_div.animate( { opacity: 1 }, 1000 );
  },
  sortDivsByRank: function( arrayOfDivs )
  {
    var tmp = [];
    for ( var it in arrayOfDivs )
    {
      if ( tmp.length < 1 ) tmp.push( arrayOfDivs[it] );
      else
      {
        var inserted = false;
        for ( var jt in tmp )
        {
          if ( this.parseRankFromBoxDiv( tmp[jt] ) < this.parseRankFromBoxDiv( arrayOfDivs[it] ) )
          {
            var elementNumber = jt + 1;
            if ( tmp.length > elementNumber )
            {
              var tmp1 = tmp.slice( 0, elementNumber );
              tmp1.push( arrayOfDivs[it] );
              var tmp2 = tmp.slice( elementNumber );
              tmp = tmp1.concat( tmp2 );
              inserted = true;
            }
            else
            {
              tmp.push( arrayOfDivs[it] );
              inserted = true;
            }
          }
        }
        if ( !inserted )
        {
          tmp.reverse();
          tmp.push( arrayOfDivs[it] );
          tmp.reverse();
        }
      }
    }
    return tmp;
  },

  /*
   * Private method displaySearchResult
   *
   * replaces top list with result of Amazon Live Search
   */
  displaySearchResult: function( display )
  {
    this.displayingSearchResult = display;
    if ( display )
    {
      $( "#button_back_to_toplist" ).show();
      $( "#div_toplist" ).hide();
      $( "#div_searchresult" ).show();
    }
    else
    {
      $( "#button_back_to_toplist" ).hide();
      $( "#div_searchresult" ).hide();
      $( "#div_toplist" ).show();
    }
  },

  /*
   * Private method parseRank
   *
   * expects string (content of a rank div)
   * returns integer (rank)
   */
  parseRank: function( textNode )
  {
    var pos = textNode.indexOf( "." );
    if ( pos < 0 ) return 1;
    return parseInt( textNode.substring( 0, pos ) );
  },
  parseRankFromBoxDiv: function( div )
  {
    var c = div.find( ".rank-div" );
    return this.parseRank( $( c[0] ).html() );
  },

  /*
   * Private method findArticle
   *
   * expects an Amazon ASIN as string
   * returns jquery DOM element object
   */
  findArticle: function( asin )
  {
    var boxes = $( ".box-233" );
    for ( var it = 0; it < boxes.length ; it++ )
    {
      if ( typeof( boxes[it].id ) == "undefined" ) continue;
      var id = boxes[it].id;
      var asinToCheck = getId( id );
      if ( asin == asinToCheck ) return $( "#"+id );
    }
    return false;
  },

  /*
   * Public method articleVoteCounted
   *
   * expects JSON object with article data
   */
  articleVoteCounted: function( obj )
  {
    var voteLink = $( "#vote_for_" + obj.asin );
    if ( voteLink.hasClass( "a_placevote_searchresult" ) )
    {
      this.updateResultBoxDiv( obj );
      return;
    }
    // rank:
    var currentRank = this.parseRank( $( "#div_rank_" + obj.asin ).html() );
    var newRank = parseInt( obj.rank );
    if ( currentRank != newRank && currentRank != 1 )
    {
      this.moveArticle( obj );
    }
    else
    {
      var voted_div = $( "#div_box_" + obj.asin );
      this.animate( voted_div );
    }
    $( "#label_yourvotes_" + obj.asin ).show();
  },

  articleBlacklisted: function( obj )
  {
    var voteLink = $( "#vote_for_" + obj.asin );
    if ( voteLink.hasClass( "a_placevote_searchresult" ) )
    {
      voteLink.replaceWith( '<span style="font-size: smaller;">Der Versand durch Amazon.de ist derzeit nicht verfügbar.</span>' );
    }
  },

  getFirstDisplayedRank: function() { return ( this.page - 1 ) * this.boxcount + 1; },
  getLastDisplayedRank:  function() { return this.page * this.boxcount; }

};

/*
 *
 * Click event listener
 *
 */

$( document ).ready( function()
{
  // Abstimmen für einen Artikel
  $( ".a_placevote" ).each( function()
  {
    $(this).click( function()
    {
      var asin = getId( $( this ).attr( "id" ) );
      wish( asin );
    });
  });
  $( "#a_livesearchpaginator_prev" ).click( function() { amazonPreviousPage(); });
  $( "#a_livesearchpaginator_next" ).click( function() { amazonNextPage(); });
});

function debug( str )
{
  if ( !Wishlist.debugging ) return;
  var content = $( "#textarea_debug" ).val();
  if ( content.length > 0 ) content += "\n";
  content += str;
  $( "#textarea_debug" ).val( content );
}

function wish( asin )
{
  $(document.body).css( "cursor", "wait" );
  $.ajax(
  {
    url: "/ajax/wunsch",
    timeout: 36000,
    type: "GET",
    data: "asin=" + asin,
    dataType: "html",
    success: callback_wish_success,
    error: callback_wish_error
  });
}

function update( asin )
{
  $.ajax(
  {
    url: "/ajax/info",
    timeout: 36000,
    type: "GET",
    data: "asin=" + asin,
    dataType: "html",
    success: callback_info_success,
    error: callback_wish_error
  });
}

/*
 *
 * Callback functions
 *
 */

function callback_info_success( data )  // deprecated
{
  $(document.body).css( "cursor", "default" );
  var pos = data.indexOf( ":" );
  if ( data.substr( 0, pos ) == "Exception" ) popupMessage( data.substr( pos+1 ) );
  else
  {
    var obj = eval( data );
    //debug( obj.asin + ": " + obj.votes + " Votes, old rank: " + currentRank + ", new rank: " + newRank + " (" + obj.title + ")" );
    if ( typeof( $( "#div_box_" + obj.asin ).attr( "id" ) ) != "undefined" )
    {
      if ( !( obj.rank < Wishlist.getFirstDisplayedRank() ) ) Wishlist.updateResultBoxDivSilently( obj )
    }
  }
}

function callback_wish_success( data )  // deprecated
{
  return;
  $(document.body).css( "cursor", "default" );
  var pos = data.indexOf( ":" );
  if ( data.substr( 0, pos ) == "Exception" )
  {
    var msg = trim( data.substr( pos+1 ) );
    if ( msg != "Nicht eingeloggt." ) popupMessage( msg );
  }
  else
  {
    var obj = eval( data );
    if ( typeof( $( "#div_box_" + obj.asin ).attr( "id" ) ) != "undefined" )
    {
      if ( obj.blacklisted == 1 )
      {
        Wishlist.articleBlacklisted( obj );
      }
      else if ( decreaseVotes() )
      {
        if ( obj.rank < Wishlist.getFirstDisplayedRank() && !Wishlist.displayingSearchResult )
        {
          // reload page -1
          if ( Wishlist.page > 1 )
          {
            //var page = Wishlist.page - 1;
            var page = Wishlist.page - getPageInterval( obj.rank, Wishlist.getFirstDisplayedRank() );
            var href = window.location.href;
            var pos  = href.lastIndexOf( "/" ) + 1;
            var href = href.substring( 0, pos ) + page;
            window.location.href = href;
          }
        }
        else Wishlist.articleVoteCounted( obj );
      }
    }
  }
}

function getPageInterval( rank, firstRankOnCurrentPage )
{
  var rankInterval = firstRankOnCurrentPage - rank;
  var pageInterval = Math.ceil( rankInterval / 10 );
  return pageInterval;
}

function callback_wish_error( data )
{
  $(document.body).css( "cursor", "default" );
  popupMessage( "HTTP Error" );
}

$.fn.egrep = function(pat)
{
  var out = [];
  var textNodes = function(n)
  {
    if (n.nodeType == Node.TEXT_NODE)
    {
      var t = typeof pat == 'string' ? n.nodeValue.indexOf(pat) != -1 : pat.test(n.nodeValue);
      if (t) out.push(n.parentNode);
    }
    else
    {
      $.each(n.childNodes, function(a, b) { textNodes(b); });
    }
  };
  this.each(function() { textNodes(this); });
  return out;
};
