/*

Title:
	Digikey Enhancements

Description:
	This is a Greasemonkey user script for Firefox that changes the \
    appearance and some of the functionality of Digikey.com.
    
Author:
	Sajid Sadi (http://consciousanima.net/)

Last Updated:
	July 13, 2007
    
License:
    This work is licensed under a Creative Commons Attribution-Share Alike 3.0 License. 
    Details at: http://creativecommons.org/licenses/by-sa/3.0/us/
    
*/

// ==UserScript==
// @name          Digikey Fixes
// @namespace     http://www.consciousanima.net/
// @description   Fix up Digikey
// @include       http://*.digikey.com/*
// @include       http://digikey.com/*
// ==/UserScript==
function addGlobalStyle(css) {
	var head, style;
	head = document.getElementsByTagName('head')[0];
	if (!head) { return; }
	style = document.createElement('style');
	style.type = 'text/css';
	style.innerHTML = css;
	head.appendChild(style);
}

function gm_fixup() {
	var ae, ce;
	
	var movePrice = GM_getValue('digikey_fixes_move_price');
	var reduceFont = GM_getValue('digikey_fixes_reduce_size');
	if (typeof movePrice == 'undefined') {
		GM_setValue('digikey_fixes_move_price', false);
		movePrice = false;
	}
	if (typeof reduceFont == 'undefined') {
		GM_setValue('digikey_fixes_reduce_size', false);
		reduceFont = false;
	}
	GM_registerMenuCommand(movePrice ? 'Leave price at end' : 'Move price to column 4', function() {
		GM_setValue('digikey_fixes_move_price', !movePrice);
		window.setTimeout(function() { window.location.reload(false); }, 100);
		});
	GM_registerMenuCommand(reduceFont ? 'Use default layout' : 'Make layout smaller', function() {
		GM_setValue('digikey_fixes_reduce_size', !reduceFont);
		window.setTimeout(function() { window.location.reload(false); }, 100);
		});

    // modify catalog link
	ae = document.evaluate("//a[contains(@href, 'Current.html')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	for (var i = 0; i < ae.snapshotLength; i++) {
	    ce = ae.snapshotItem(i);
		if (ce.href) {
			ce.href = 'http://www.digikey.com/scripts/DkSearch/dksus.dll?KeywordSearch&Stock=1';
		}
	}

    // modify start page
	ae = document.evaluate("//input[@type='checkbox']", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	for (var i = 0; i < ae.snapshotLength; i++) {
		ce = ae.snapshotItem(i);
		if (ce.id == 'stock') ce.checked = true;
	}
		
	// the header field tends to have random case...
	ae = document.evaluate("//input[translate(@name,'ABCDEFGHIJKLMNOPQRSTUVWXYZ','abcdefghijklmnopqrstuvwxyz')='keywords']/ancestor::td[@class='headertopcell']", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	for (var i = 0; i < ae.snapshotLength; i++) {
		ce = ae.snapshotItem(i);
		var span = document.createElement('span');
		span.innerHTML = ' [ <input type="checkbox" value="1" name="Stock" checked="checked"/>stock only ] ';
		ce.appendChild(span);
		break;
	}

    // modify and format tables
	ae = document.evaluate("//table[contains(., 'Quantity Available')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	if (ae.snapshotLength > 0) {
        var table = ae.snapshotItem(0);
        var tab = document.evaluate("//th[contains(., 'Extended Price')]/ancestor::table", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
        if (tab.snapshotLength == 0) {
            gm_modifyTable(table);
			if (movePrice) {
				gm_movePrice(table);
			}
        } else {
            table.cellSpacing = 0;
            table.border = 0;

			// tab is the pricing sub-table... space it a bit
			tab = tab.snapshotItem(tab.snapshotLength-1);
			tab.style.marginLeft = '10px';

			// find the details table from the current location and fix it
			var tmp0 = document.evaluate("//th[contains(., 'Quantity Available')]/ancestor::table[@border=1]", table, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
            if (tmp0.snapshotLength) gm_fixColorsSpec(tmp0.snapshotItem(0), 'Pricing');
			
			// find the secondary details table and fix it
			var tmp0 = document.evaluate("//a[contains(., 'Packaging')]/ancestor::table[@border=1]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
			if (tmp0.snapshotLength) gm_fixColorsSpec(tmp0.snapshotItem(tmp0.snapshotLength - 1), 'Product Information');
			
        }
	}

    // flatten out labels to take less space
    ae = document.evaluate("//label[contains(., 'In Stock')]", document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0; i < ae.snapshotLength; i++) {
        ce = ae.snapshotItem(i);
        var last = null;
        while (ce) {
            switch (ce.nodeName) {
            case 'BR': 
                if (!i) last = ce; 
                break;
            case 'LABEL': 
                if (last) {
                    last.parentNode.removeChild(last);
                    last = null;
                };
                break;
            }
            if (i) {
                if (ce.nodeName == 'BR') {
                    last = ce;
                    ce = ce.nextSibling;
                    last.parentNode.removeChild(last); 
                    last = null; 
                } else {
                    ce = ce.nextSibling;
                }
            } else {
                ce = ce.nextSibling;
            }
        }
	}
		
    // add the css styles to make things look a little nicer	
	var styles = 'ul { margin-top: 0.25em;} h3 { margin-bottom: 0; } a { text-decoration: none} .pricing td { border-color: #ccc; }';
	styles += '.gm_table{margin-top:0.5em; border-bottom: 1px solid #ddd; } .spaced{ margin-bottom: 5em } .gm_table a{text-decoration:none;font-weight:bold;} .gm_table .gm_h a{color:#fff} .gm_table .gm_h a:visited{color:#fff} .gm_table a:visited{color:#99d} .gm_table tr:hover{background:#ddd} .gm_c1{background: #eee;} .gm_table td, .gm_table th{padding:2px 1em 2px 2px} th{text-align:left;vertical-align:top;} .gm_h{background: #889;color:#fff} h3.header{background:#445;color:#fff;font-size:150%;padding: 1px 3px;margin: 0;}';
	if (reduceFont) {
		styles += ' body * { font: 11px Tahoma, Helvetica, Arial, san-serif; line-height: 1.2;}';
		styles += '.gm_table td, .gm_table th{padding:2px;} .gm_table td { border-right:1px solid #ddd;} .gm_h td,.gm_table tr td:last-child { border-right: 0 none }';
	} else {
		styles += ' body * { font: 12px Tahoma, Helvetica, Arial, san-serif; line-height: 1.3;}';
	}
    styles += 'tr.gm_h:hover { background: #889 }';
	
	addGlobalStyle(styles);
}

function gm_movePrice(table) {
	for (var i = 0; i < table.rows.length; i++) {
		var price = table.rows[i].removeChild(table.rows[i].cells[table.rows[i].cells.length - 2]);
		table.rows[i].insertBefore(price, table.rows[i].cells[3]);
	}
}

function gm_fixColorsSpec(t, title) {
	t.border = 0;
    t.cellPadding = 0;
	t.cellSpacing = 0;	
    t.className = 'gm_table';
    var h = document.createElement('H3');
    h.className = 'header';
    h.innerHTML = title;
    t.parentNode.insertBefore(h, t);
	for (var i = 0; i < t.rows.length; i++) {
		t.rows[i].className = ((i % 2 == 0) ? 'gm_c1' : '');
	}
}

function gm_fixColors(t) {
	for (var i = 0; i < t.rows.length; i++) {
		t.rows[i].className = (i < 2) ? 'gm_h' : ((i % 2 == 0) ? 'gm_c1' : '');
	}
}

function gm_clickfn() {
	var t = document.getElementById('gm_table');
	var rows = new Array();
	for (var i = 2; i < t.rows.length; i++) {
		rows[i-2] = t.rows[i];
	}
	var movePrice = GM_getValue('digikey_fixes_move_price');
	var sortFn = function(a, b) {
		return gm_sortfn(movePrice ? 3 : a.cells.length-2, a, b);
	};
	rows.sort(sortFn);
	for (var i = 0; i < rows.length; i++) {
		t.tBodies[0].appendChild(rows[i]);
	}
	gm_fixColors(t);
}

function gm_calcValue(elem) {
    var price = parseFloat(elem.textContent);
    if (!price) return 1e6;
    var t = elem.previousSibling;
    while (t && t.nodeName && t.nodeName != 'TD') {
        t = t.previousSibling;
    }
    if (!t) return 1e6;
    var v = price * t.textContent;
    if (!v) return 1e6;
	return v;
}

function gm_sortfn(pos, a, b) {
	var va = gm_calcValue(a.cells[pos]);
	var vb = gm_calcValue(b.cells[pos]);
	if (va == vb) return 0;
	if (va < vb)  return -1;
	return 1;
}

function gm_modifyTable(ce) {
	ce.border = 0;
	ce.cellPadding = 0;
	ce.cellSpacing = 0;
	
	ce.className = 'gm_table spaced';
	ce.id = 'gm_table';
	
	var trs = ce.rows;
	if (ce.rows.length > 2) {
		var c = ce.rows[1].cells[ce.rows[1].cells.length - 2];
		c.innerHTML = '<img src="http://dkc3.digikey.com/US/Images/Up.gif"/>';
		c.addEventListener('click', gm_clickfn, false);
	}
	gm_fixColors(ce);
	for (var i = 2; i < ce.rows.length; i++) {
		var c = ce.rows[i].cells;
		var as = c[c.length-1].getElementsByTagName('a');
		if (as.length > 0) {
			var a = as[0].cloneNode(false);
			for (var j = 0; j < c[1].childNodes.length; j++) {
				a.appendChild(c[1].removeChild(c[1].childNodes[0]));
			}
			c[1].appendChild(a);
		}
	}
}

gm_fixup();