// ==UserScript==
// @name                Renew listing
// @version             2.1
// @date                2009-11-16
// @author              Ian Malpass ( ian AT etsyhacks DOT com )
// @namespace           etsy.com
// @description         Adds link to renew the item when viewing an item in your shop
// @include             http://www.etsy.com/view_listing.php*
// @include             http://www.etsy.com/your_shop.php*
// ==/UserScript==

/*
This script will first check to see if you're viewing an item in your own shop. If you are, then it adds a link to
renew the item to the right-hand panel, under the "report to Etsy" link.
*/

var refreshUri = "data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%10%00%00%00%10%08%06%00%00%00%1F%F3%FFa%00%00%00%01sRGB%00%AE%CE%1C%E9%00%00%00%06bKGD%00%FF%00%FF%00%FF%A0%BD%A7%93%00%00%00%09pHYs%00%00%0B%12%00%00%0B%12%01%D2%DD~%FC%00%00%00%07tIME%07%D9%01%15%13'%3A%A1%EB%1F%A4%00%00%02SIDAT8%CB%B5%93%CFK%D3a%1C%C7%DF%CF%F3%9D%FB%F1u%EBkN%A6)%9AZ%986%05%A3Qh%3F(%93%D1%A5Ct%ED%14%04u%10%0A%82%88.%5D%F2%14%9D%22%FB%03%3A%D4%25%94%0A%3CH%19%8A%2B%17%B2%DA%94a%5B%C5l%BA%A9%9B%CE%7D%F7%DD%F7%D7%9E%A7%93c%85%11!%BDo%9F%C3%E7%C5%E7%F5%7C%3E%0F9%FF%C0%85%DD%84b%97%B1T%16%5Dm%BDw%0CC%BF%E8%AA%DE%DB%CD%98%B9%A9%19%EA%94%DD*%8E%84%16%03%93%7F%02%90m%85%F6%A6%CE%87%DE%E6c7%0E7%F6%11%C6%19l%16%11%8C%97%F06%FAl%BD%A8%17n%86%16%03Ow%02%08%07%FD64%D7%B7%9Dn%AD%EF%7C%229%EA%C8%86%92%86j%16%90W3P%F4%1Cz%9AN%89k%F2%8FAw%8D'%BA%B2%9E%88%EE%A8%40%08%BD%E6q5%93%E4f%DC%C8%177%A6%01%14%24%D1%7D%C6%DB%D4%E7%CC%14%928%D22%B0%E7%7D%FC%D5poG%DF%B8nj%AC%D6%E9%19%2F1s%3E%10%99%18%A2%00%209k%FB3%85%15%9E%CA%26.%85c%C1%81p%2Cx!%A7d%BC%A1%C4%BBe%9BE%04%E7%25%1Cm%1D%ECrX%AB_PBo%5D%E8%B9~V%12%EB%AE%96%B7%60%11%AC%9E%AC%9C%0E~MF_n%8F%16%8E%05%13%AA%5E%F0GSA%5D%A0U%A8%B6J%90%C4%BA%93%ED%9E%EE%BB%94P%A8%86%B2T%06%08T0%14U%9E%FE%DD%EF%D3%97%0F%F3Y9%F5%BA%C4%0C0%CE%E0m%ECw%F9Z%FCb%D1%C8C%D1%B66%CBo%A0h%F2w%CEY%B2%B2%F9%B8w%E0%B6nj%5D%8A%26%9B%F3%CB%01%F8%F6%FB%C18%85%CE4%C8Z%16%84%D0%E52%A0%A8%CA%B3n%A9%A1c%BB%B9%FB%80%CF%B6Oj%BD%7F%EE%D0e!W%5C%83%C9%0D%00%80f*%A0%84b5%9F%E0%9C%B3PY%C1-5%ACU%5Ee%24%FEQKo%25FF%3F%3F%DAZH%CF%C0d%06Lf%40%A0U%B0R%3BrJ%A6%08%60%AE%0CXZ%8D%DDsX%9D%A9J%85%40db(%A7%AC7%C6W%C3%8Fg%E2c%DF%22%C9)n%17D8%AA%5C%D0Kjrvar%EC%97K%FC%5B%FA%7B%FC'(%A1%C3N%7B%8DO7%D5%E7o%E6F%AF%FC%13%E0%BF%FD%C6%9F%F8i%0E%B9%EAQ%0Cf%00%00%00%00IEND%AEB%60%82";

var l = 0;
var links = document.getElementsByTagName( 'a' );

var shopPattern = /(profile|shop).php\?user_id=(\d+)/; // find shop links
var yourShop; // what's your shop ID?
var thisShop; // what's the current shop's ID?
for ( 1; l < links.length; l++ ) {
    var link = links[ l ];
    if ( link.href ) {
        var match = shopPattern.exec( link.href );
        if ( match ) {
            // we have a shop link
            if ( link.title == 'Your Shop' ) {
                // this is the link to your shop in the top nav bar
                yourShop = match[ 2 ];
                break;
            }
        }
    }
}

if ( document.location.href.indexOf( 'view_listing.php' ) > -1 ) {
    getThisShop();
} else {
    thisShop = yourShop;
}
if ( yourShop == thisShop ) {
    getToken( yourShop );
}

// find out which shop we're looking at
function getThisShop () {
    for ( 1; l < links.length; l++ ) {
        var link = links[ l ];
        if ( link.href ) {
            var match = shopPattern.exec( link.href );
            if ( match ) {
                // we have a shop link
                if ( link.innerHTML == 'profile' ) {
                    // this is the link to the shop in the "seller info" box
                    thisShop = match[ 2 ];
                    // if we find this, we're done
                    return;
                }
            }
        }
    }
}

// add the renew link(s) to the page
function addLink( yourShop ) {
    var nnc   = GM_getValue( yourShop + '_nnc' );
    if ( nnc == null ) return;
    if ( document.location.href.indexOf( 'view_listing.php' ) > -1 ) {
        addLinkToListing( yourShop, nnc );
    } else {
        addLinkToYourShop( yourShop, nnc );
    }
}

function addLinkToListing ( yourShop, nnc ) {
    // it's our item
    // find the listing ID
    var match = window.location.search.match( /listing_id=(\d+)/ );
    var listing_id = match[ 1 ];

    // form to send the relisting data to the relisting component
    var form = document.createElement( 'form' );
    form.action = "http://www.etsy.com/renew_listings_expiring.php";
    form.method = "POST";
    form.innerHTML = '<input type="hidden" name="renew_listing_id[]" value="' + listing_id + '" /><input type="hidden" name="_nnc" value="' + nnc + '" /><input type="hidden" name="submit" value="renew" />';
    document.body.appendChild( form );
            
    var ul = getElementsByClassName( 'page-tools' )[ 0 ];
        
    var li = document.createElement( 'li' );
    var img = document.createElement( 'span' );
    img.style.backgroundImage = "none";
    img.className = 'icon';
    img.innerHTML = '<img src="' + refreshUri + '" width="15" height="15" />';
    li.appendChild( img );

    var link = document.createElement( 'a' );
    link.innerHTML = 'Renew this item';
    link.addEventListener( 'click', function () { form.submit() }, false ); // only parse the page on click
    link.style.cursor = 'pointer';
    link.style.color = '#0192B5';
    link.removeAttribute( 'href' ); // going to use an onclick handler instead

    li.appendChild( link );
    ul.appendChild( li );
}

function addLinkToYourShop( yourShop, nnc ) {
    var reactivatePattern = /reactivate_listing.php\?listing_id=(\d+)/; // find reactivate links
    var form = generateForm( null, nnc );
    for ( 1; l < links.length; l++ ) {
        var link = links[ l ];
        if ( link.href ) {
            var match = link.href.match( reactivatePattern );
            if ( match ) {
                // found a link - get the listing ID
                var listing_id = match[ 1 ];
                var cell = link.parentNode;

                // create a "renew" link
                var renew = document.createElement( 'a' );
                renew.style.cursor = 'pointer';
                renew.innerHTML = '&bull; renew';
                renew.addEventListener( 'click', genHandler( form, listing_id ), true );

                // add our "renew" link to the same table cell
                cell.appendChild( document.createElement( 'br' ) );
                cell.appendChild( renew );
            }
        }
    }
}

// event handler closure generator
function genHandler( form, listing_id ) {
    return function () {
        form.elements.namedItem( 'renew_listing_id[]' ).value = listing_id;
        form.submit();
    }
}

// add a form to the page to submit the renewal request
function generateForm ( listing_id, nnc ) {
    if ( listing_id == null ) listing_id = "";
    // form to send the relisting data to the relisting component
    var form = document.createElement( 'form' );
    form.action = "http://www.etsy.com/renew_listings_expiring.php";
    form.method = "POST";
    form.innerHTML = '<input type="hidden" name="renew_listing_id[]" value="' + listing_id + '" /><input type="hidden" name="_nnc" value="' + nnc + '" /><input type="hidden" name="submit" value="renew" />';
    document.body.appendChild( form );
    return form;
}

// find the nonce token and trigger the UI update when we have it
function getToken ( shop ) {
    var token = GM_getValue( shop + '_token' );
    var cookies = document.cookie.split( /;\s*/ );
    var cToken;
    for ( var c = 0; c < cookies.length; c++ ) {
        var bits = cookies[ c ].split( '=' );
        if ( bits[ 0 ] == 'token' ) {
            cToken = bits[ 1 ];
            break;
        }        
    }
    if ( token && cToken == token && GM_getValue( shop + '_nnc' ) ) {
        addLink( shop );
        return;
    }
    var nnc;
    var inputs = document.getElementsByTagName( 'input' );
    for ( var i = inputs.length - 1; i >= 0; i-- ) {
        if ( inputs[ i ].name == '_nnc' ) {
            saveNnc( shop, inputs[ i ].value, token );
            addLink( shop );
            return;
        }
    }
    GM_xmlhttpRequest( {
        method: 'GET',
        url: 'http://www.etsy.com/expiring_listings.php',
        headers: { Cookie: document.cookie },
        onload: function ( response ) { parseUpdate( shop, response, cToken ) }
    } );
}

function parseUpdate ( shop, response, token ) {
    if ( response.status == 200 ) {
        var d = document.createDocumentFragment();
        d.innerHTML = response.responseText;
        var nnc = response.responseText.match( /<[^>]*name="_nnc"[^<]*>/ );
        if ( nnc ) {
            var match = nnc[0].match( /value="([^"]+)"/ );
            if ( match ) {
                saveNnc( shop, match[ 1 ], token );
                addLink( shop );
            }
        }
    }
}

function saveNnc ( shop, nnc, token ) {
    GM_setValue( shop + '_nnc', nnc );
    GM_setValue( shop + '_token', String( token ) );
}

// utility function to replicate getElementsByClassName() on older Firefoxes
function getElementsByClassName ( class, node ) {
    if ( node == null ) node = document;
    if ( node.getElementsByClassName ) {
        return node.getElementsByClassName( class );
    } else {
        var classElements = new Array();
        var els = node.getElementsByTagName( '*' );
        var elsLen = els.length;
        var pattern = new RegExp("(^|\\s)"+class+"(\\s|$)");
        for (i = 0, j = 0; i < elsLen; i++) {
            if ( pattern.test(els[i].className) ) {
                classElements[j] = els[i];
                j++;
            }
        }
        return classElements;
    }
}


