var trackableHostPieces = [location.host, '.cnet.com', '.cnettv.com', '.news.com', '.com.com', '.download.com'];
var noTag = new RegExp("[\\?&]tag=");
var __linkClickObservations_preMain__ = new Array();
var __linkClickObservations_postMain__ = new Array();

/**
 * Builds up an array of all the functions that should be observed as part of the onClick.
 * This is to allow easy access into this framework, for doing other items as dictated by the site.
 *
 * @param func the function you want added to the process
 * @param afterMainTrackingTagFunc send true if you want this added after the "trackCnetLinks" function.  default is before.
 */
function addLinkClickObservation(func, afterMainTrackingTagFunc) {
    if (afterMainTrackingTagFunc) {
        __linkClickObservations_postMain__.push(func);
    } else {
        __linkClickObservations_preMain__.push(func);
    }
}

/**
 * Do auto-tracking of links, across the page, via hi-jacking the onClick of all the links...
 */
Event.observe(window, "load", function() {
    // add our main tracking function here, so that we could have given the opportunity to completely override it if needed.
    var links = document.links;
    for (var i = 0; i < links.length; i++) {
        // see if there is an existing onClick for this link...
        if (undefined == links[i].onclick) {
            // ah, ok, then we can attach to it...
            links[i].onclick = trackCnetLinks;
            // that's it... that function does the rest...
        }
    }
});


/**
 * The function that finds best tag, and appends it accordingly.
 * Can be overriden, in order to provide more specific requirements
 *
 * @param event this is passed automatically when this is made the direct reactor to the onclick
 * @param daLink used to allow manually calling with whatever specific Anchor object you like.
 */
function trackCnetLinks(event, daLink) {
    if (!daLink) daLink = this; // cause we have multiple ways this is accessed...

    // short circuit the logic if this is just an attempt to anchor to another part of the page...
    if (daLink.href.indexOf('#') >= 0 && daLink.href.startsWith(location.href)) return true;
    
    // loop through each of the pre-main observable link functions, and run them...
    for (var j = 0; j < __linkClickObservations_preMain__.length; j++) {
        __linkClickObservations_preMain__[j](daLink);
    }

    // now do our logic...
    if (!daLink.search.match(noTag)) {
        for (var j = 0; j < trackableHostPieces.length; j++) {
            if (daLink.host.indexOf(trackableHostPieces[j]) >= 0) {
                var tag = findCnetTag(daLink);
                daLink.search = (daLink.search.length == 0) ? "?tag=" + tag : daLink.search + "&tag=" + tag;
                break;
            }
        }
    }

    // and run all the post logic...
    for (var j = 0; j < __linkClickObservations_postMain__.length; j++) {
        __linkClickObservations_postMain__[j](daLink);
    }

    // if we got here we just need to let it handle itself... cause we don't know enough about it to add tracking...
    return true;
}

/**
 * Traversing the DOM up, till it finds an id= somewhere...
 */
function findCnetTag(obj) {
    var par = obj;
    while (par) {
        if (null != par.id && par.id.length > 0) {
            return par.id;
        }
        par = par.parentNode;
    }
    return 'nt'; // for 'No Tag'
}