function scRealTimePrice( pitId, pId, spId, ysId ) {
        pitId = (pitId && (pitId = pitId.toString()))? pitId : "product-info-table";
        pId = (pId && (pId = pId.toString()))? pId : "pitPriceBx";
        spId = (spId && (spId = spId.toString()))? spId : "pitSalePriceBx";
        ysId = (ysId && (ysId = ysId.toString()))? ysId : "pitYouSaveBx";
        
        var addListener = function() {
                if ( window.addEventListener ) {
                        return function(el, type, fn) {
                                el.addEventListener(type, fn, false);
                        };
                } else if ( window.attachEvent ) {
                        return function(el, type, fn) {
                                var f = function() {
                                        fn.call(el, window.event);
                                };
                                el.attachEvent('on'+type, f);
                        };
                } else {
                        return function(el, type, fn) {
                                el['on'+type] = fn;
                        };
                }
        }();
        
        function forceFloat( num ) {
                /*
                        forceFloat - Private - Forces data of an undefined type into an floating point value
                        PARAMETERS: num - should be an floating point value, but may be of a different type
                        RETURN: an floating point value
                */
                return (isNaN(num = parseFloat((typeof num === Number)? num : num.toString().replace(/^.*?([\d\.]+).*?$/, "$1"))))? 0.0 : num;
        }
        
        function toPrice( num, currency ) {
                /*
                        toPrice - Private - Converts a number value into a formatted price string; commas are added at thousand mark, decimals are forced to 2 digits, and the currency is added to the front of the string.
                        PARAMETERS: num - should be an floating point or integer value; currency should be a character or string value
                        RETURN: a string of the number as a price in a given currency
                */
                if (num) {
                        num = forceFloat(num).toFixed(2).toString();
                        var intEnd = num.indexOf(".") - 3;
                        for (var i = intEnd, j = 0; i > j; i -= 3) {
                                num = num.substring(0, i) + "," + num.substring(i, num.length);
                        }
                        num = num;
                } else {
                        num = "0.00";
                }
                if (currency) {
                        if (typeof currency !== String) {
                                currency = currency.toString();
                        }
                } else {
                        currency = "";
                }
                return currency + num;
        }
        
        this.init = function() {
                /*
                        init - Public - Starts the process of scraping the product info table and updating price values
                        PARAMETERS: none
                        RETURN: none
                */
                var pit = document.getElementById(pitId);
                if (pit) {
                        var ins = pit.getElementsByTagName("input");
                        var trs = pit.getElementsByTagName("tr");
                        if (ins && trs) {
                                var insToCheck = [];
                                for (var i = 0, j = ins.length; i < j; i++) {
                                        var inType = ins[i].type.toLowerCase();
                                        if ((inType == "radio") || (inType == "checkbox")) {
                                                insToCheck.push(ins[i]);
                                        }
                                }
                                var selsToCheck = pit.getElementsByTagName("select");
                                
                                if (insToCheck || selsToCheck) {
                                        var prices = [];
                                        prices[pId] = document.getElementById(pId);
                                        prices[spId] = document.getElementById(spId);
                                        prices[ysId] = document.getElementById(ysId);
                                        
                                        if (prices[pId] || prices[spId] || prices[ysId]) {
                                                var priceExp = /\$([\d\,\.]+)/;
                                                function stripPrice( str ) {
                                                        /*
                                                                stripPrice - Private - Strips out a price value from a string
                                                                PARAMETERS: str - the string to parse for a price
                                                                RETURN: the price as a floating point number
                                                        */
                                                        str = str.match(priceExp);
														fstr = str[1].replace(',','');
                                                        str = (str)? forceFloat(fstr) : 0;
                                                        return str;
                                                }
                                                
                                                function regexPrice( num ) {
                                                        /*
                                                                regexPrice - Private - Converts a price to a price string that can be used in a regex replace
                                                                PARAMETERS: num - the price as a floating point number
                                                                RETURN: a string value of the price (dollar sign is escaped by another dollar sign for regex use)
                                                        */
                                                        return ((window.scRTPcurrency && (scRTPcurrency != "$"))? scRTPcurrency : "$$") + toPrice(num);
                                                }
                                                
                                                var basePrices = [];
                                                if (prices[pId]) {
                                                        basePrices[pId] = stripPrice(prices[pId].innerHTML);
                                                }
                                                if (prices[spId]) {
                                                        basePrices[spId] = stripPrice(prices[spId].innerHTML);
                                                }
                                                
                                                function updatePrices() {
                                                        /*
                                                                updatePrices - Private - checks opts for price updates, calculates new totals, and outputs the new values in their respective (HTML element) containers
                                                                PARAMETERS: none
                                                                RETURN: none
                                                        */
                                                        var price = basePrices[pId];
                                                        var salePrice = basePrices[spId];
                                                        var optExp = /\((.+?)\)/;
														
                                                        for (var i = 0, j = insToCheck.length; i < j; i++) {
                                                                if (insToCheck[i].checked) {
                                                                        var optCost = insToCheck[i].value.match(optExp);
                                                                        if (optCost) {
																				switch (optCost[1].substring(0,1)){
																					case '+':
                                                                                		price += forceFloat(optCost[1]);
                                                                                		salePrice += forceFloat(optCost[1]);
																					break;
																					case '-':
                                                                                		price -= forceFloat(optCost[1]);
                                                                                		salePrice -= forceFloat(optCost[1]);
																					break;
																					default:
                                                                                		price += forceFloat(optCost[1]);
                                                                                		salePrice += forceFloat(optCost[1]);
																					break;
																				}
                                                                        }
                                                                }
                                                        }
                                                        for (var i = 0, j = selsToCheck.length; i < j; i++) {
                                                                var optCost = selsToCheck[i].options[selsToCheck[i].selectedIndex].value.match(optExp);
                                                                if (optCost) {
																		switch (optCost[1].substring(0,1)){
																			case '+':
																				price += forceFloat(optCost[1]);
																				salePrice += forceFloat(optCost[1]);
																			break;
																			case '-':
																				price -= forceFloat(optCost[1]);
																				salePrice -= forceFloat(optCost[1]);
																			break;
																			default:
																				price += forceFloat(optCost[1]);
																				salePrice += forceFloat(optCost[1]);
																			break;
																		}
                                                                }
                                                        }
                                                
                                                        if (prices[pId]) {
                                                                prices[pId].innerHTML = prices[pId].innerHTML.replace(priceExp, regexPrice(price));
                                                        }
                                                        if (prices[spId]) {
                                                                prices[spId].innerHTML = prices[spId].innerHTML.replace(priceExp, regexPrice(salePrice));
                                                        }
                                                        if (prices[ysId]) {
                                                                var youSave = price - salePrice;
                                                                var youSavePer = Math.round(youSave / price * 100);
                                                                prices[ysId].innerHTML = prices[ysId].innerHTML.replace(priceExp, regexPrice(youSave));
                                                                prices[ysId].innerHTML = prices[ysId].innerHTML.replace(/[\d]+\%/, youSavePer + "%");
                                                        }
                                                }
                                                
                                                // initialize option input listeners
                                                for (var i = 0, j = insToCheck.length; i < j; i++) {
                                                        addListener(insToCheck[i], "click", updatePrices);
                                                }
                                                for (var i = 0, j = selsToCheck.length; i < j; i++) {
                                                        addListener(selsToCheck[i], "change", updatePrices);
                                                }
                                                updatePrices(); // run an initial sweep to sync prices out of the box
                                        }
                                }
                        }
                }
        };
}
