// ==UserScript==
// @name                Subtotals
// @version             1.7
// @date                2009-05-12
// @author              Ian Malpass ( ian AT etsyhacks DOT com )
// @namespace           etsy.com
// @description         Adds item and shipping subtotals to your receipts
// @include             http://www.etsy.com/receipt.php?order_id=*
// @include             http://www.etsy.com/receipt_print.php?order_id=*
// ==/UserScript==

/*
This script totals up the cost of items and shipping and inserts subtotals
at the bottom of the receipt pages, above the final total.

It uses the classes generated by the "printable receipt enhancer" script 
(http://www.etsyhacks.com/greasemonkey/printable_receipt_enhancer/) when
working with the printable receipt view. You'll need to have it installed
and running before this script for it to work on the printable page.

It assumes that the currency symbol is "$". I'll have to fix that in the
future.
*/

var text = [];
var totalRow;

// The data cells have different class names and layouts in the two 
// receipt views, but once we have them in a suitable array, we can
// capture the data the same way

if ( window.location.pathname.match( 'receipt.php' ) ) {
    // all the currency values are "green_text" on the regular receipt page
    var textList = getElementsByClassName( 'green_text' );
    var offset = ( textList.length % 2 == 0 ) ? 1 : 0;
    for ( var t = 0; t < textList.length - offset; t++ ) {
        if ( t % 2 == 1 ) {
            // shipping cost - get the quantity from an adjacent cell
            // we infer the total shipping cost from the total item
            // cost and the grand total at the end
            row = textList[ t ].parentNode;
            qty = row.parentNode.rows[ row.rowIndex - 1 ].cells[ 2 ];
            text.push( qty );
        } else {
            // item cost
            text.push( textList[ t ] );
        }
    }
    // the last green_text value is the total
    totalRow = text[ text.length -1 ].parentNode;
} else if ( window.location.pathname.match( 'receipt_print.php' ) ) {
    // the currency values have classes defined by the "printable receipt
    // enhancer" script
    var prices = getElementsByClassName( 'itemPriceCell' );
    var quantities = getElementsByClassName( 'itemQuantityCell' );
    // merge them into a single array, like the NodeList we get for the
    // regular receipt
    for ( var i = 0; i < prices.length; i++ ) {
        text.push( prices[ i ] );
        text.push( quantities[ i ] );
    }
    // and work out the total row using the generated ID
    totalRow = document.getElementById( 'itemsTotalValue' );
    if ( totalRow ) {
        text.push( totalRow );
        totalRow = totalRow.parentNode;
    }
}

if ( text.length > 0 ) {
    // we have values - we wouldn't if the "printable receipt enhancer"
    // script wasn't installed, or hadn't yet run
    var total = { items: 0, shipping: 0 };
    // extract the numbers
    for ( var t = 0; t < text.length - 1; t += 2 ) {
        var qty = Number( text[ t + 1 ].innerHTML );
        var price = Number( text[ t ].innerHTML.match( /[\d\.]+/ ) );
        total.items += qty * price;
    }
    total.orderTotal = Number( text[ text.length -1 ].innerHTML.match( /[\d\.]+/ ) );
    total.shipping = total.orderTotal - total.items;

    // do some string formatting
    for ( var i in total ) {
        total[ i ] = String( total[ i ] );
        if ( total[ i ].indexOf( '.' ) > -1 ) {
            // this is a hack to work around a stringification error that cropped up
            total[ i ] = String( Math.round( 100 * total[ i ] ) / 100 );
        }
        if ( total[ i ].indexOf( '.' ) == -1 ) total[ i ] += '.'
        while ( total[ i ].lastIndexOf( '.' ) > ( total[ i ].length - 3 ) ) {
            total[ i ] += '' + '0';
        }
        total[ i ] = '$' + total[ i ];
    }

    // and add the extra rows - they have the same structure as the 
    // total row
    var itemTotal = totalRow.cloneNode( true );
    var shippingTotal = totalRow.cloneNode( true );
    itemTotal.cells[ 0 ].innerHTML = 'Items:';
    itemTotal.cells[ 1 ].innerHTML = total.items;
    itemTotal.cells[ 0 ].style.paddingBottom = '0px';
    itemTotal.cells[ 1 ].style.paddingBottom = '0px';
    itemTotal.cells[ 0 ].id = 'itemsSubtotalLabel';
    itemTotal.cells[ 1 ].id = 'itemsSubtotalValue';
    shippingTotal.cells[ 0 ].style.paddingTop = '0px';
    shippingTotal.cells[ 1 ].style.paddingTop = '0px';
    shippingTotal.cells[ 0 ].innerHTML = 'Shipping:';
    shippingTotal.cells[ 1 ].innerHTML = total.shipping;
    shippingTotal.cells[ 0 ].id = 'shippingSubtotalLabel';
    shippingTotal.cells[ 1 ].id = 'shippingSubtotalValue';
    totalRow.parentNode.insertBefore( itemTotal, totalRow );
    totalRow.parentNode.insertBefore( shippingTotal, totalRow );
}

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;
    }
}



