  
var customerRegistry = (function () {
    var UNDEF,
        creg,
        
        callAjax = function ( qs, act, fn, errfn, finalfn ) {
            var rspfn = function ( rsp ) {
                    if ( errfn(rsp) )
                        fn(rsp);
                    finalfn(rsp);
                };
            
            errfn = errfn || function (rsp) {
                if ( rsp )
                    return true;
                
                alert('ERROR: call to server to perform the "' + act + '" action returned no data.');
                return false;
            };
            
            finalfn = finalfn || function(){};
            
            if ( qs ) {
                if ( !qs.match(/^&/) )
                    qs = '&' + qs;
            } else {
                qs = '';
            }
            
            qs = 'action=customerRegistry&subaction=' + act + qs;
            ajaxObj.call(qs, rspfn);
        },
        
        deleteConfirmationMsg = 'You have requested to delete this item from your registry or wish list. '
                              + 'This action cannot be undone. Are you sure you would like to delete it?',
        
        gebi = function ( id ) {
            return document.getElementById(id);
        },
        
        safeParseInt = function ( val, defaultValue ) {
            val = parseInt(val);
            return !isNaN(val) ? val : defaultValue;
        },
        
        dir = function ( elem, dir ) {
            var matches = [],
                current = elem[dir];
            
            while ( current && current.ownerDocument ) {
                if ( current.nodeType == 1 )
                    matches.push(current);
                current = current[dir];
            }
            
            return matches;
        },
        
        codir = function ( elem, dir, pred ) {
            var cur = elem[dir];
            
            pred = pred || function () { return true; }
            
            while ( cur && cur.ownerDocument ) {
                if ( cur.nodeType == 1 && pred.apply(cur) )
                    return cur;
                cur = cur[dir];
            }
            
            return null;
        },
        
        trim = function ( s ) {
            return String(s).replace(/^\s+|\s+$/g, '');
        },
        
        removeElem = function ( elem ) {
            var parent = elem.parentNode;
            parent.removeChild(elem);
            return elem;
        };
        
        
        
    
    creg = {
        addItem: function ( itemId ) {
            var formId, formSelect, msgElem;
            
            itemId = itemId || '';
            formId = 'form_select' + itemId;
            
            formSelect  = creg.checkOptionsChosen(formId);
            msgElem     = gebi('msg' + itemId);
           
            if ( !formSelect ) {
                alert("Unexpected system error: cannot locate appropriate form for item id: " + itemId + ".");
                return;
            }
            
            disableForm(formSelect);
            msgElem.innerHTML = '';
            
            var formfields = ajaxObj.getForm(formId);

            callAjax(formfields.substr(1), 'addItem', function (rsp) {
     
                if ( !rsp )
                    rsp = {};
                if ( !rsp.error )
                    rsp.error = "An unexpected error occured while trying to add the item to the registry.";
                
                msgElem.innerHTML = !rsp.viewLink
                                  ? rsp.error
                                  :   'The item(s) have been added to your registry or wish list. '
                                    + '<a href="' + rsp.viewLink + '">View your list</a>';
            }, false, function (rsp) {
                enableForm(formSelect);
            });
        },
        
        updateItem: function ( regItemId ) {
            var pvs,
                qty = creg.determineQty(regItemId, 'qty-requested-');
            
            if ( qty === false )
                return;
            
            postVars = 'id=' + regItemId + '&qty=' + qty;
            callAjax(postVars, 'updateItem', function (rsp) {
                if ( !rsp  || rsp.error ) {
                    alert('The item could not be updated: ' + (rsp.error || 'the server did not return a response') );
                    return;
                }
                
                creg.recalculateQty(regItemId, rsp.remaining);
            });
            
        },
        
        
        recalculateQty: function ( regItemId, qtyRemaining ) {
            var qtyElem  = gebi('qty-requested-' + regItemId);
                parentTd = codir(qtyElem, 'parentNode', function () { return this.tagName.toUpperCase() == 'TD'; }),
                sibling  = codir(parentTd, 'nextSibling', function () { return this.tagName.toUpperCase() == 'TD'; });
            
            sibling.innerHTML = Math.max(qtyRemaining, 0);
        },
        
        deleteItem: function ( regItemId ) {
            var postVars;
            
            if ( !confirm(deleteConfirmationMsg) ) {
                return;
            }
            
            postVars = 'id=' + regItemId;
            callAjax(postVars, 'deleteItem', function (rsp) {
                if ( !rsp.id && !rsp.error ) {
                    rsp.error = 'An unexpected error occurred while attempting to delete the item.';
                }
                
                if ( rsp.error ) {
                    // Do error stuff
                    return;
                }
                
                var qreq = gebi('qty-requested-' + regItemId),
                    irow = codir(qreq, 'parentNode', function () { return this.tagName.toUpperCase() == 'TR'; });
                
                removeElem(irow);
            });
        },
        
        addToCart: function ( regItemId, btnElem ) {
            var infoElem = gebi('cart-item-info-' + regItemId),
                qtyElem  = gebi('qty-add-to-cart-' + regItemId),
                postVars = infoElem.value,
                qty;
            
            // Handle legacy issues
            postVars = postVars.replace(/(sub)?action=.*?&/g, '');
            postVars = postVars.replace(/productQty=.\d*?&?/, '');
            
            qty = safeParseInt(qtyElem.value, 0);
            qtyElem.value = qty;
            if ( qty <= 0 ) {
                alert('' + qty + ' is not a valid quantity.');
                return;
            }
            
            postVars = 'action=addToCart&' + postVars + '&productQty=' + qty + '&registryItemId=' + regItemId;
            
            //postVars = postVars.replace(/(sub)?action=.*?&/g, '');
            
            ajaxObj.call(postVars, function (rsp) {
                var itemAdded, viewCart, msgElem;
                
                if ( rsp[1] == 1 ) {
                    itemAdded = language['itemAddedRfp'];
                    viewCart  = language['viewCartRfp'];
                } else {
                    itemAdded = language['itemAdded'];
                    viewCart  = language['viewCart'];
                }
                
                if ( !( msgElem = gebi('cart-message-' + regItemId) ) ) {
                    msgElem = document.createElement('p');
                    msgElem.id = 'cart-message-' + regItemId;
                    
                    (function (elem) {
                        var tdCont = codir(btnElem, 'parentNode', function () { return this.tagName.toUpperCase() == 'TD'});
                        
                        tdCont.appendChild(elem);
                    })(msgElem);
                }
                
                msgElem.innerHTML = itemAdded + '<br /><a href="/cart.html">' + viewCart + '</a>';
                
                // check cart view
                ajaxObj.call('action=checkCartView', cartView);
            });
        },
        
        determineQty: function ( regItemId, idPrefix, alertOnError ) {
            var qty,
                qtyElem = gebi( idPrefix + regItemId );
            
            alertOnError = alertOnError !== false;
            
            if ( !qtyElem || qtyElem.value === UNDEF ) {
                if ( alertOnError )
                    alert('Cannot locate appropriate quantity.');
                return false;
            }
            
            qty = safeParseInt(qtyElem.value);
            if ( qty < 0 ) {
                if ( alertOnError )
                    alert('Quantity given is invalid.');
                return false;
            }
            
            return qty;
        },
        
        checkUrl: function ( elem, originalValue ) {
            var url = elem.value;
            
            // filter
            url = creg.filterUrl(url);
            elem.value = url;
            
            if ( url == original )
                return;
            
            if ( str.length < 4 || str.length > 60 ) {
                // Write error out
                return;
            }
            
            callAjax('url=' + url, 'checkUrl', function (rsp) {
                if ( rsp.error ) {
                    // do stuff
                    return;
                }
                
                if ( rsp.filteredValue != url ) {
                    elem.value = rsp.filteredValue;
                }
                
                if ( rsp.valid )
                    return;
                
                // Use rsp.failureMessage
                
            });
        },
        
        filterUrl: function ( url ) {
            url = String(url);
            
            return url.replace(/\s+/g, '-')
                      .replace(/-+/g, '-')
                      .replace(/[\w-]+/g, '')
                      .replace(/^-|-$/g, '')
                      .toLowerCase();
        },
        
        checkOptionsChosen: function ( formId, success, failure ) {
            var chk, frm = gebi(formId);
            
            success = success || function () {};
            failure = failure || function () {
                alert( language['chooseAllOptions'] );
            };
            
            disableForm(frm);
            
            chk = checkBanks(frm) != 0;
            chk ? success(frm) : failure(frm);
            
            enableForm(frm);
            
            return chk ? frm : false;
        }
    };
    
    return creg;
})();

function gebi( id ) {
    return document.getElementById(id);
}

