// Copyright (c) 2008, Chewy Byte Solutions. All rights reserved.
// This is a Greasemonkey user script.
// You will need to install Greasemonkey from [https://addons.mozilla.org/en-US/firefox/addon/748] or [http://greasemonkey.mozdev.org/] before using this script.
//
// DEVELOPMENT ('TESTED WORKING') ENVIRONMENT:
// OS: Windows XP SP3 32-bit (http://www.microsoft.com)
// Internet Browser: Firefox 3.0 (http://www.mozilla.com/en-US/)
// Required Internet Browser Addon: Greasemonkey version 0.8.20080609.0 (https://addons.mozilla.org/en-US/firefox/addon/748)
//
// LICENSE:
// - Free for non-profit personal usage upon total agreement and acceptance of this license.
// - Author reserves all exclusive rights for distribution of this script. (DO NOT link directly to script download URL. Link to the download page.)
// - Author reserves all rights to seek and take legal actions for any usage/distribution/modification deems unappropriate by the author and solely by the author.
// - Author will have the final say in all other usage/distribution/modification circumstances not covered by this short, simple license agreement.
// - Author reserves all rights to amend terms and conditions in this license as deems appropriate by the author and solely by the author.
// - Use this script at your own risk(s). Author will not be held liable for any loss from usage or this script.
// - Do not expect the author to give your 'after sales' services. Use the script as is or don't use it at all. However, constructive feedbacks will be greatly appreciated.
// - There is no guarantee this script will work, especially in other versions of OS, browsers and/or Greasemonkey.
// - The only guarantee author gives is that this script DOES NOT contain any intentionally included malicious codes.
// - In general terms, this script DOES NOT contain/download/generate/produce any kind virus/malware/security exploits/adware. The only 'ad' is the credit to author as stated here.
// - Author is reachable at admin [at|@] chewybyte [dot|.] com OR admin [at|@] chewybyte [dot|.] net
//
// ==UserScript==
// @name           Lelong Utilities
// @author         Yen of Chewy Byte Solution (http://www.chewybyte.com)
// @namespace      yen@cbs
// @description    Utility script(s) for lelong.com.my
// @include        http://*.lelong.com.my/*
// @version        2008.07.18
// ==/UserScript==
function listingPage_Main() { // [START] Auction Listing Page ##########

AddJavascript((<r><![CDATA[

var aU = String.fromCharCode(8679);
var aD = String.fromCharCode(8681);
var hideClosed = false;
var tblData = new Array(1);
tblData[0] = ['c0','c1', 'c2', 'c3','c4','c5', 'price', 'time'];
	
if (IdentifyTables() && ReadTables(tblData)) {
	ModifyTableData(tblData);
	ShowTable(tblData, null);
}

function IdentifyTables() {
	var i, j;
	var tblIdCount = 0;
	var tbls = document.getElementsByTagName('table');
	
	if (!tbls) { return false; }
	
	for (i = 0; i < tbls.length; i++) {
		// Pagination table
		if (tbls[i].rows[0].cells[0].className == 'sm9' && tbls[i].id != 'pageTbl') {
			
			// Remove table attributes
			while (tbls[i].attributes && tbls[i].attributes.length > 0) {
				tbls[i].removeAttribute(tbls[i].attributes[0].nodeName);
			}
			tbls[i].id = 'pageTbl';
			tbls[i].className = 'pageTbl';
			
			for (j = 0; j < tbls[i].rows[0].cells.length; j++) {
				while (tbls[i].rows[0].cells[j].attributes && tbls[i].rows[0].cells[j].attributes.length > 0) {
					tbls[i].rows[0].cells[j].removeAttribute(tbls[i].rows[0].cells[j].attributes[0].nodeName);
				}
				tbls[i].rows[0].cells[j].className = 'pageTblCell' + j.toString();
			}
		}
	
		// List tables
		if (tbls[i].getAttribute('width') == '80%' && tbls[i] && tbls[i].rows && tbls[i].rows[0].cells && tbls[i].rows[0].cells.length == 6) { // Potential list table
		
			if (tbls[i].rows[0].cells[2].innerHTML.match(/Price /)) { // First list table
				tbls[i].id = 'lstTbl0';
			}
		
			else if (tbls[i].rows[1] && tbls[i].rows[1].cells[2].innerHTML.match(/RM /)) { // Subsequent list tables
				tblIdCount++;
				tbls[i].id = 'lstTbl' + tblIdCount.toString();
			}
		}
		
		// Advertisement table
		if (tbls[i].className == 'bt bl br bb') { tbls[i].id = 'advertTbl_RCol'; }
	}
	
	// Remove advert elements
	if (document.getElementById('advertTbl_RCol') != null) { document.getElementById('advertTbl_RCol').parentNode.removeChild(document.getElementById('advertTbl_RCol')); }
	while (document.getElementsByTagName('iframe')[0] != null) {
		document.getElementsByTagName('iframe')[0].parentNode.removeChild(document.getElementsByTagName('iframe')[0]);
	}
	
	if (document.getElementById('lstTbl0') != null) {
		return true;
	} else {
		return false;
	}
}

function ReadTables(data) {
	var c0, c1, c2, c3, c4, c5;
	var tbl, i = 0;
	
	while (document.getElementById('lstTbl' + i.toString()) != null) {
		tbl = document.getElementById('lstTbl' + i.toString());
		for (j = 0; j < tbl.rows.length; j++) {
			for (k = 0; k < 6; k++) {
				eval('c' + k.toString() + ' = tbl.rows[j].cells[k].innerHTML;');
			}
			if ((c0 + c1 + c2 + c3 + c4 + c5).length != 0) {
				if (i == 0 && j == 0) {
					data[0] = [c0, c1, c2, c3, c4, c5, 'price', 'time'];
				} else {
					data.push([c0, c1, c2, c3, c4, c5, CalcPrice(c2), CalcTime(c5)]);
				}
			}
		}
		i++;
	}
	
	return true;
}

function ModifyTableData(data) {
	if (data.length > 1) {
	
		data[0][2] = '<span id="priceAsc" class="sort" onclick="ShowTable(tblData, this.id);">'+aD+'</span><span id="priceDesc" class="sort" onclick="ShowTable(tblData, this.id);">'+aU+'</span>' + data[0][2];
		data[0][5] = '<span id="timeAsc" class="sort" onclick="ShowTable(tblData, this.id);">'+aD+'</span><span id="timeDesc" class="sort" onclick="ShowTable(tblData, this.id);">'+aU+'</span>' + data[0][5];
		
		for (i = 1; i < data.length; i++) {
			data[i][2] = data[i][2].replace(/font-weight: bold;">RM /,'">RM ');
			data[i][2] += '<div class="totalPrice">RM ' + FormatPrice(data[i][6]) + '</div>';
			if (data[i][4].match(/ Bids/)) {
				data[i][4] = '<span class="bidHl">' + data[i][4] + '</span>';
			} else if (data[i][4].match(/\d{3,} Views/)) {
				data[i][4] = '<span class="viewHl">' + data[i][4] + '</span>';
			}
		}
	}
	return;
}

function ShowTable(data, sorter) {
	var titleRow, tbl, newRow, newCell;
	var closedItemExists = false;
	var i = 0;
	
	if (sorter == null) {
		sorter = GetSortCommand();
	}
	
	AppendSortCommandToLinks(sorter);
	
	if (document.getElementById('qcksrch') && document.getElementById('qcksrch_sort') == null) {
		var newInput = document.createElement('input');
		newInput.id = 'qcksrch_sort';
		newInput.type = 'hidden';
		newInput.name = 'SortBy';
		newInput.value = sorter;
		document.getElementById('qcksrch').appendChild(newInput);
	} else if (document.getElementById('qcksrch_sort')) {
		document.getElementById('qcksrch_sort').value = sorter;
	}
	
	tbl = document.getElementById('lstTbl0');
	if (tbl == null) { return; }
	
	// Delete existing rows
	while (tbl.rows[0] != null) {
		tbl.deleteRow(0);
	}
	
	// Sort table data
	titleRow = data.shift();
	data = data.sort(eval(sorter));
	data.unshift(titleRow);
	
	// Add new rows with data
	for (i = 0; i < data.length; i ++) {
		newRow = tbl.insertRow(-1);
		if (i == 0) { newRow.id = 'titleRow'; } // Title row.
		if (i % 2 == 1) { newRow.style.backgroundColor = '#e8e8e8'; } // Alternate row background color.
		for (j = 0; j < 6; j++) { // Insert cells
			if (data[i][5].match(/Closed/) && hideClosed == true) {
			} else {
				newCell = newRow.insertCell(-1);
				newCell.className = 'column' + j.toString();
				newCell.innerHTML = data[i][j];
			}
			if (data[i][5].match(/Closed/)) { closedItemExists = true; } // Check if any item is 'Closed'
		}
	}
	
	// Manage sorter arrows
	document.getElementById(sorter).className += ' currentSort';
	document.getElementById(sorter).setAttribute('onclick', '');
	
	// Remove existing list tables
	i = 1;
	while ( document.getElementById( 'lstTbl' + i.toString() ) != null ) {
		tbl.parentNode.removeChild( document.getElementById('lstTbl' + i.toString()) );
		i++;
	}
	
	// Add 'Hide Closed Item' button
	if (document.getElementById('pageTbl') != null && closedItemExists == true && hideClosed == false) {
		var newTd = document.createElement('td');
		newTd.className = 'hideClosedItemCell';
		newTd.setAttribute('onclick', 'HideClosedItems()');
		newTd.innerHTML = '<div>Hide<br />Closed</div>';
		document.getElementById('pageTbl').rows[0].appendChild(newTd);
	}
	
	// Add top pagination table
	if (document.getElementById('pageTblTop') == null && document.getElementById('pageTbl') != null) {
		var newPageTbl = document.getElementById('pageTbl').cloneNode(true);
		newPageTbl.id = 'pageTblTop';
		document.getElementById('lstTbl0').parentNode.insertBefore(newPageTbl, document.getElementById('lstTbl0'));
	}

	return;	
}

function HideClosedItems() {
	while (document.getElementsByClassName('pageTblCell3 hideClosedItemCell')[0]) {
		document.getElementsByClassName('pageTblCell3 hideClosedItemCell')[0].parentNode.removeChild(document.getElementsByClassName('pageTblCell3 hideClosedItemCell')[0]);
	}
	hideClosed = true;
	ShowTable(tblData, null);
	return;
}

function GetSortCommand() {
	if (document.URL.match(/SortBy=priceAsc|SortBy=priceDesc|SortBy=timeAsc|SortBy=timeDesc/)) {
		return document.URL.match(/priceAsc|priceDesc|timeAsc|timeDesc/)[0];
	} else {
		return 'priceAsc';
	}	
}

function AppendSortCommandToLinks(command) {
	var i;
	var links = document.getElementsByTagName('a');
	
	for (i = 0; i < links.length; i++) {
		if (links[i].href.match(/Auc\/List\/List.asp/) || links[i].href.match(/http:\/\/list\.lelong\.com\.my\/L\.asp/)) { // Listing page
			if (links[i].href.match(/SortBy=priceAsc|SortBy=priceDesc|SortBy=timeAsc|SortBy=timeDesc/)) { // Link contains sort command parameters
				links[i].href = links[i].href.replace(/SortBy=priceAsc|SortBy=priceDesc|SortBy=timeAsc|SortBy=timeDesc/, 'SortBy=' + command);
			} else if (links[i].href.match(/\?/i)) { // Link already contains other parameters
				links[i].href += '&SortBy=' + command;
			} else { // Link does not contain any parameters
				links[i].href += '?SortBy=' + command;
			}
		}
	}
	return;
}

function CalcPrice(data) {
	var prices = data.match(/RM [\d,]{1,}\.\d\d/g);
	if (prices != null && prices[0] != null) {
		prices[0] = parseFloat(prices[0].replace(/RM/,'').replace(/,/,'').replace(/\s/g, ''));
		if  (prices[1] != null) {
			prices[1] = parseFloat(prices[1].replace(/RM/,'').replace(/,/,'').replace(/\s/g, ''));
			prices[0] = parseInt((prices[0] + prices[1]) * 100);
			prices[0] = prices[0] / 100;
		}
		return prices[0].toString();
	} else {
		return '0';
	}
}

function CalcTime(time) {
	var d = 0;
	var h = 0;
	var m = 0;
	
	if (time.match(/Closed/)) { return -1; }
	time = time.replace(/&nbsp;/g, '');
	time = time.replace(/\s/g, '');
	
	if (time.match(/\d{1,}d/) != null) { d = parseInt(time.match(/\d{1,}d/)); }
	if (time.match(/\d{1,}h/) != null) { h = parseInt(time.match(/\d{1,}h/)); }
	if (time.match(/\d{1,}m/) != null) { m = parseInt(time.match(/\d{1,}m/)); }
	if (time.match(/\d{1,}min/) != null) { m = parseInt(time.match(/\d{1,}min/)); }
	
	if (d != 0 && isFinite(d)) { d *= 1440; }
	if (h != 0 && isFinite(h)) { h *= 60; }
	
	return (d + h + m).toString();
}

function FormatPrice(price) {
	var formattedPrice = price;
	
	if (!formattedPrice.toString().match(/\./)) {
		formattedPrice += '.00';
	} else if (formattedPrice.toString().length - formattedPrice.toString().search(/\./) == 2) {
		formattedPrice += '0';
	}
	
	if (formattedPrice.toString().length > 6) {
		formattedPrice = formattedPrice.toString().substr(0, formattedPrice.toString().length - 6) + ',' + formattedPrice.toString().substr(-6);
	}
	
	return formattedPrice;
}

function priceAsc(a, b) {
    var x = a[6];
    var y = b[6];
    return x-y;
}

function priceDesc(a, b) {
    var x = a[6];
    var y = b[6];
    return y-x;
}

function timeAsc(a, b) {
    var x = a[7];
    var y = b[7];
    return x-y;
}

function timeDesc(a, b) {
    var x = a[7];
    var y = b[7];
    return y-x;
}]]></r>).toString()); // >>>>>>>>>> [End] AddJavascript

AddCSS((<r><![CDATA[
#lstTbl0, .pageTbl {
	width: 90% !important;
	margin-left:4% !important;
}
#lstTbl0 .totalPrice {
	font-size:140%;
	font-weight:bold;
	color:#f00;
}
#lstTbl0 .bidHl {
	font-weight:bold;
	color:#0080ff;
}
#lstTbl0 .bidHl span {
	font-size:140%;
	color:#f00 !important;
}
#lstTbl0 .viewHl {
	font-weight:bold;
	color:#000;
}
#lstTbl0 span.sort {
	padding:0px;
	margin:0px 3px;
	cursor:pointer;
	color:#2e6ab1;
	background-color:#fff;
	border:1px solid #2e6ab1;
	font:normal normal bold 120% Verdana;
}
#lstTbl0 span.currentSort {
	cursor:default;
	color:#fff;
	background-color:#2e6ab1;
}
#lstTbl0 #titleRow td {
	border:1px solid #e8e8e8;
}
#lstTbl0 .column0 {
	width:70px;
}
#lstTbl0 .column1 {
}
#lstTbl0 .column2 {
	text-align:center;
}
#lstTbl0 .column3 {
	text-align:center;
}
#lstTbl0 .column4 {
	text-align:center;
}
#lstTbl0 .column5 {
	text-align:center;
}
.pageTbl {
	margin:0px 0px;
	border:1px solid #2e6ab1;
	border-spacing:0px;
}
.pageTbl td, .pageTbl .pages, .pageTbl form, .pageTbl input {
	padding:0px !important;
	margin:0px !important;
}
.pageTbl td {
	padding:3px 0px !important;
	font-size:110%;
}
.hideClosedItemCell {
	cursor:pointer;
	font-size:80% !important;
	font-weight:bold;
	text-align:center;
	background-color:#2e6ab1;
	color:#fff;
}
.hideClosedItemCell div {
	margin:0px 0px 0px 2px;
}
]]></r>).toString()); // >>>>>>>>>> [END] AddCSS
} // [END] Auction Listing Page ##########

function itemPage_Main() {// [START] Item Page ##########

AddJavascript((<r><![CDATA[

var i, saleCell, startCell, shippingCell, highBidCell;
var tds = document.getElementsByTagName('td');
	
for (i = 0; i < tds.length; i++) {
	if (tds[i].className == 'rtext' && tds[i].innerHTML.match(/Sale Price/) && tds[i+2].innerHTML.match(/RM /)) {
		i += 2;
		saleCell = tds[i];
		saleCell.id = 'saleCell';
	} else if (tds[i].className == 'rntext' && tds[i].innerHTML.match(/Start Price/) && tds[i+2].innerHTML.match(/RM /)) {
		i += 2;
		startCell = tds[i];
		startCell.id = 'startCell';
	} else if (tds[i].className == 'rntext' && tds[i].innerHTML.match(/Highest Bid/) && tds[i+2].innerHTML.match(/RM /)) {
		i += 2;
		highBidCell = tds[i];
		highBidCell.id = 'highBidCell';
	} else if (tds[i].className == 'rtext' && tds[i].innerHTML.match(/Peninsular /) && tds[i].innerHTML.match(/Sabah \/ Sarawak /) && tds[i].innerHTML.match(/RM /)) {
		shippingCell = tds[i];
		shippingCell.id = 'shippingCell';
	}
}

if (saleCell != undefined && shippingCell != undefined) {
	saleCell.innerHTML += '<span id="totalPrice" class="sale">' + ItemPage_CalcSale(saleCell.innerHTML, shippingCell.innerHTML) + '</span>';
} else if (startCell != undefined && highBidCell != undefined && shippingCell != undefined) {
	if (highBidCell.innerHTML.match(/Below Reserve/)) {
		highBidCell.innerHTML += '<span id="totalPrice" class="belowReserve">' + ItemPage_CalcBid(startCell.innerHTML, highBidCell.innerHTML, shippingCell.innerHTML) + '</span>';
	} else {
		highBidCell.innerHTML += '<span id="totalPrice">' + ItemPage_CalcBid(startCell.innerHTML, highBidCell.innerHTML, shippingCell.innerHTML) + '</span>';
	}
}

function ItemPage_CalcSale(sale, ship) {
	var totalPrice;
	var salePrice = sale.match(/RM [\d,]{1,}\.\d\d/);
	var shipPrice = ship.match(/RM [\d,]{1,}/);
	
	if (salePrice != null) {
		salePrice = parseFloat(salePrice[0].replace(/RM/,'').replace(/,/,''));
		if (shipPrice == null) {
			totalPrice = salePrice;
		} else {
			shipPrice = parseFloat(shipPrice[0].replace(/RM/,'').replace(/,/,''));
			totalPrice = salePrice + shipPrice;
		}
	}
	
	if (totalPrice == undefined || totalPrice == null) {
		return '?.??';
	} else {
		totalPrice = totalPrice.toString();
	}

	if (!totalPrice.match(/\./)) {
		totalPrice += '.00';
	} else if (totalPrice.length - totalPrice.search(/\./) == 2) {
		totalPrice += '0';
	}
	if (totalPrice.length > 6) {
		totalPrice = totalPrice.substr(0, totalPrice.length - 6) + ',' + totalPrice.substr(-6);
	}
	return 'RM ' + totalPrice;
}

function ItemPage_CalcBid(start, bid, ship) {
	var totalPrice;
	var startPrice = start.match(/RM [\d,]{1,}\.\d\d/);
	var bidPrice = bid.match(/RM [\d,]{1,}\.\d\d/);
	var shipPrice = ship.match(/RM [\d,]{1,}/);
	
	if (startPrice != null && bidPrice != null) {
		startPrice = parseFloat(startPrice[0].replace(/RM/,'').replace(/,/,''));
		bidPrice = parseFloat(bidPrice[0].replace(/RM/,'').replace(/,/,''));
		if (startPrice > bidPrice) {
			totalPrice = startPrice;
		} else {
			totalPrice = bidPrice;
		}
		if (shipPrice != null) {
			shipPrice = parseFloat(shipPrice[0].replace(/RM/,'').replace(/,/,''));
			totalPrice += shipPrice;
		}
	}
	
	if (totalPrice == undefined || totalPrice == null) {
		return '?.??';
	} else {
		totalPrice = totalPrice.toString();
	}
	
	if (!totalPrice.match(/\./)) {
		totalPrice += '.00';
	} else if (totalPrice.length - totalPrice.search(/\./) == 2) {
		totalPrice += '0';
	}
	
	if (totalPrice.length > 6) {
		totalPrice = totalPrice.substr(0, totalPrice.length - 6) + ',' + totalPrice.substr(-6);
	}
	return 'RM ' + totalPrice;
}
]]></r>).toString()); // >>>>>>>>>> [End] AddJavascript

AddCSS ((<r><![CDATA[
#highBidCell span.redtext {
	color:#000;
}
span#totalPrice {
	margin:0px 10px;
	font-size:200%;
	font-weight:bold;
	color:#fff;
	padding:2px 4px;
	background-color:#0080ff;
}
span.sale {
	font-size:150% !important;
}
span.belowReserve {
	color:#999 !important;
	background-color:#ccc !important;
	border:1px solid #999 !important;
}
]]></r>).toString()); // >>>>>>>>>> [END] AddCSS
} // [END] Item Page ##########

// ########## [START] Common Functions ##########
function AddJavascript(content) {
	var newElement = document.createElement('script');
	newElement.setAttribute('type', 'text/javascript');
	newElement.innerHTML = content;
	document.body.appendChild(newElement);
	return;
}

function AddCSS(content) {
	var newElement = document.createElement('style');
	newElement.setAttribute('type', 'text/css');
	newElement.innerHTML = content;
	document.getElementsByTagName('head')[0].appendChild(newElement);
	return;
}
// ########## [END] Common Functions ##########

// ########## [START] Main Entry-point ##########
if (document.URL.match(/Auc\/List\/List.asp/)) {
	GM_log('Lelong Utilities Script: Listing page.');
	listingPage_Main();
} else if (document.URL.match(/\/Auc\/List\/[^\/]+\.htm/) || document.URL.match(/\/Auc\/List\/DetailStd\.asp/)) {
	GM_log('Lelong Utilities Script: Item page.');
	itemPage_Main();
} else {
	GM_log('Lelong Utilities Script: No matching utilities for page ' + document.URL.toString());
}
// ########## [END] Main Entry-point ##########