// ==UserScript==
// @name           Feature This Item
// @version        1.0
// @date           2009-05-22
// @author         Ian Malpass ( ian AT etsyhacks DOT com )
// @namespace      etsy.com
// @description    Feature or unfeature a listing from the View Listing page
// @include        http://www.etsy.com/view_listing.php?*
// @include        http://www.etsy.com/rank_featured.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 links to
feature the item to the right-hand panel, under the "report to Etsy" link.

It also updates its list of "currently featured" items if you visit the "rank featured" page.
*/

var links = document.getElementsByTagName( 'a' );
var shopPattern = /shop.php\?user_id=(\d+)/; // find shop links
var yourShop; // what's your shop ID?
var thisShop; // what's the current shop's ID?
var l; // link counter

if ( document.location.href.indexOf( 'rank_featured.php' ) > -1 ) {
    getShop( true ); // find out who we are
    parseFeatures( document.body.innerHTML ); // extract the "currently featured" list
} else {
    getShop(); // find out who we are
    if ( yourShop == thisShop ) {
        // our shop - add the links
        var last = GM_getValue( yourShop + '_lastUpdate' ) || 0;
        last = Number( last );
        var now = new Date;
        if ( ( now.valueOf() - last ) < 600000 ) {
            // have a pretty up-to-date list of featured items
            decorateShop();
        } else {
            // check for changes to featured items (will then decorateShop())
            getFeatures();
        }
    }
}

// function to go through the tree to find out who we are, and optionally who the current shop is
function getShop ( yourShopOnly ) {
    l = 0;
    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[ 1 ];
                    if ( yourShopOnly ) return
                } else if ( link.firstChild && link.firstChild.data && link.firstChild.data.indexOf( "'s shop" ) > -1 ) {
                    // this is the link to the shop in the "seller info" box
                    thisShop = match[ 1 ];
                    // if we find this, we're done
                    return;
                }
            }
        }
    }
}

// add the link to the page
function decorateShop () {
    // find the listing ID
    var match = window.location.search.match( /listing_id=(\d+)/ );
    var listing_id = match[ 1 ];

    // search for the "report to Etsy" link
    for ( 1; l < links.length; l++ ) {
        var link = links[ l ];
        if ( link.firstChild && link.firstChild.data && link.firstChild.data == 'Report this item to Etsy' ) {
            reportRow = link.parentNode;
            while ( reportRow && reportRow.nodeName != 'TR' ) reportRow = reportRow.parentNode;
            // alter the report link to become the "feature item" link
            var featRow = reportRow.cloneNode( true );
            var featLink = featRow.getElementsByTagName( 'a' )[ 0 ];
            featLink.removeAttribute( 'href' ); // going to be doing client-side AJAXy stuff
            featLink.style.cursor = 'pointer';
            var featImg = featRow.getElementsByTagName( 'img' )[ 0 ];
            // add the event listener
            featLink.addEventListener( 'click', function () { toggleFeature( listing_id, featLink, featImg ) }, true );
            // set the text and icon
            updateFeatureUI( listing_id, featLink, featImg );
            // attach to document, under the "report to Etsy" link
            reportRow.parentNode.insertBefore( featRow, reportRow.nextSibling );
            break;
        }
    }
}

// send the AJAX request to toggle the feature; same URL toggles on and off
function toggleFeature ( listing_id, featLink, featImg ) {
    // loading
    featImg.src = '/images/ajax-loader.gif';
    featImg.width = 15;
    featImg.height = 15;

    // send the request
    GM_xmlhttpRequest( {
        url: 'http://www.etsy.com/your_shop.php?feature_listing_id=' + listing_id,
        method: 'GET',
        headers: { Cookie: document.cookie },
        onload: function ( response ) {
            if ( response.status == 200 ) {
                // work out if we're adding or removing, and update the features list
                var features = eval( GM_getValue( yourShop + '_features' ) || '([])' );
                var removed = false;
                for ( var f = 0; f < features.length; f++ ) {
                    if ( features[ f ] == listing_id ) {
                        features.splice( f, 1 );
                        removed = true;
                        break;
                    }
                }
                if ( ! removed ) {
                    features.push( listing_id );
                }
                updateFeatures( features ); // store the updated array
                updateFeatureUI( listing_id, featLink, featImg ); // alter the UI
            }
        }
    } );
}

// set the UI elements up to match the listing's featured/unfeatured status
function updateFeatureUI( listing_id, featLink, featImg ) {
    var features = eval( GM_getValue( yourShop + '_features' ) || '([])' );

    var toggleText = 'Feature this item';
    var imgSrc = '/images/icon_star_on.gif';
    for ( var f = 0; f < features.length; f++ ) {
        if ( features[ f ] == listing_id ) {
            toggleText = 'Unfeature this item';
            imgSrc = '/images/icon_star_off.gif';
            break;
        }
    }

    featLink.innerHTML = toggleText;
    // tweak the icon
    featImg.src = imgSrc;
    featImg.alt = toggleText;
    featImg.width = 15;
    featImg.height = 14;
}

// get the list of currently-featured items
function getFeatures () {
    GM_xmlhttpRequest( {
        url: 'http://www.etsy.com/rank_featured.php',
        method: 'GET',
        headers: { Cookie: document.cookie },
        onload: function ( response ) {
            if ( response.status != 200 ) return;
            var text = response.responseText;
            parseFeatures( text ); // update the list of features
            decorateShop(); // now add the UI elements
        }
    } );
}

// parse the content of the "rank featured" page to extract currently featured listings
function parseFeatures ( text ) {
    var features = text.match( /rank_featured.php\?unfeature_listing_id=\d+/g );
    var ids = [];
    if ( features ) {
        for ( var f = 0; f < features.length; f++ ) {
            ids.push( features[ f ].substr( features[ f ].indexOf( '=' ) + 1 ) );
        }
    }
    updateFeatures( ids ); // update the list
}

function updateFeatures( ids ) {
    GM_setValue( yourShop + '_features', uneval( ids ) ); // store the list of featured items
    var now = new Date;
    GM_setValue( yourShop + '_lastUpdate', String( now.valueOf() ) ); // and the last update time
}



