function TabStripClass(workingArea, objectName) {
    /* Public properties */
    this.workingArea = workingArea;
    this.isPaused = false;
    this.tabs = [];
    this.objectName = objectName;
    this.currentTabIndex = 0;
    this.tabSwitchDelay = 25;   // in seconds
    this.prefetchDelay = 0.5;    // in seconds
    
    /* Private properties */
    var self = this;
    var prefetchTimeoutHandle;
    var renderTimeoutHandle;

    /* Constructor */
    
    var uls = this.workingArea.getElementsByTagName("ul");
    for(var i=0; i<uls.length; i++) {
        if(hasClass(uls[i], "rssNavLinks")) {
            var rssLinksUL = uls[i];
        }
    }

    var lis = rssLinksUL.getElementsByTagName("li");
    for(var i=0; i<lis.length; i++) {
        lis[i].getElementsByTagName("a")[0].setAttribute("href", "javascript: void(0);");
        if(hasClass(lis[i], "prevBtn")) {
            addEvent(lis[i].getElementsByTagName("a")[0], "click", function() {
                self.cancelTabLoadSchedules();
                self.tabs[getPreviousTabIndex()].renderTab();
            });
        }

        if(hasClass(lis[i], "pauseBtn")) {
            addEvent(lis[i].getElementsByTagName("a")[0], "click", function() {
                if(self.isPaused) {
                    self.isPaused = false;
                    self.startCycling();
                } else {
                    self.isPaused = true;
                    self.cancelTabLoadSchedules();
                }
            });
        }

        if(hasClass(lis[i], "nextBtn")) {
            addEvent(lis[i].getElementsByTagName("a")[0], "click", function() {
                self.cancelTabLoadSchedules();
                self.tabs[getNextTabIndex()].renderTab();
            });
        }
    }
    
    /* Public Members */
    this.startCycling = function() {
        for(var i=0; i<this.tabs.length; i++) {
            this.tabs[i].tabIndex = i;
            this.tabs[i].parentObjectName = this.objectName;
        }
        
        this.tabs[this.currentTabIndex].renderTab();
    }
    
    this.scheduleNextTabLoad = function() {
        if(!this.isPaused) {
            prefetchTimeoutHandle = setTimeout(this.objectName + ".tabs[" + getNextTabIndex() + "].prefetchFeed();", this.prefetchDelay * 1000);
            renderTimeoutHandle = setTimeout(this.objectName + ".tabs[" + getNextTabIndex() + "].renderTab();", this.tabSwitchDelay * 1000);
        }
    }
    
    this.cancelTabLoadSchedules = function() {
        clearTimeout(prefetchTimeoutHandle);
        clearTimeout(renderTimeoutHandle);
    }
    
    /* Private Methods */
    function getNextTabIndex() {
        if(self.currentTabIndex + 1 >= self.tabs.length)
            return 0;
        else
            return (self.currentTabIndex + 1);
    }
    
    function getPreviousTabIndex() {
        if(self.currentTabIndex - 1 < 0) {
            return self.tabs.length - 1;
        } else {
            return self.currentTabIndex - 1;
        }
    }
}

function TabClass(tabListItem) {
    /* Public properties */
    this.listItem = tabListItem;
    this.rssUrl;
    this.content;
    this.renderingMode = "defaultTopFeeds";
    this.tabContentArea = this.listItem.parentNode.parentNode.getElementsByTagName("div")[0];
    this.parentObjectName;
    this.tabIndex;
    this.subtitle;
    this.callStatus = 0;    // 0 = uninitialized, 1 = in progress, 2 = completed
    this.onTabDataLoaded = function() {}
    
    /* Private properties */
    var self = this;
    var renderingModes = [];
    var isSpinnerShown = false;
    var prefetchTimeoutHandle;
    var renderTimeoutHandle;
    
    /* Constructor */
    this.listItem.getElementsByTagName("a")[0].setAttribute("href", "javascript: void(0);");
    
    addEvent(this.listItem.getElementsByTagName("a")[0], "click", function() {
        var parentObject = eval(self.parentObjectName);
        parentObject.cancelTabLoadSchedules();
        parentObject.isPaused = true;
        self.renderTab();
    })
    
    /* Public Methods */
    this.renderTab = function() {
        var ulNode = this.listItem;
        while(ulNode.nodeName.toLowerCase() != "ul")
            ulNode = ulNode.parentNode;
        
        var lis = ulNode.getElementsByTagName("li");
        
        for(var i=0; i<lis.length; i++) {
            if(hasClass(lis[i], "selected"))
                removeClass(lis[i], "selected");
        }
        
        addClass(this.listItem, "selected");
        
        if(this.callStatus == 0) {
            showSpinner();
            this.prefetchFeed();
            setTimeout(this.parentObjectName + ".tabs[" + this.tabIndex + "].renderTab()", 200);
        } else if(this.callStatus == 1) {
            setTimeout(this.parentObjectName + ".tabs[" + this.tabIndex + "].renderTab()", 200);
        } else if(this.callStatus == 2) {
            hideSpinner();
            renderingModes[self.renderingMode](this.content, this.subtitle);
            
            var parentObject = eval(this.parentObjectName);
            parentObject.currentTabIndex = this.tabIndex;
            parentObject.scheduleNextTabLoad();
        }
    }
    
    this.prefetchFeed = function() {
        var xmlconvertor = new XmlToJSONConvertor();
        if(this.callStatus != 2) {
            xmlconvertor.loadXML(this.rssUrl, function(data) {
                self.onTabDataLoaded();
                self.content = data;
                self.callStatus = 2;
            })
        }
    }
    
    /* Private Methods */
    function showSpinner() {
        if(!isSpinnerShown) {
            removeChildren(self.tabContentArea);
            
            self.tabContentArea.appendChild(createElem("div", {
                content: "Loading...",
                cssClass: "spinner"
            }));
            
            self.tabContentArea.appendChild(createElem("div", {cssClass: "clear"}));
            
            isSpinnerShown = true;
        }
    }
    
    function hideSpinner() {
        removeChildren(self.tabContentArea);
    }
    
    function formatDateShort(dateString) {
        var inputDate = new Date(dateString);
        return (inputDate.getMonth() + 1) + "/" + inputDate.getDate() + "/" + inputDate.getFullYear().toString().substr(2);
    }
    
    function formatDateLong(dateString) {
        var inputDate = new Date(dateString);
        var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
        
        return monthNames[inputDate.getMonth()] + " " + inputDate.getDate() + ", " + inputDate.getFullYear();
    }
    
    function getThumbnailURL(url) {
        var urlPieces = url.split(".");
        var returnURL = "";
        
        for(var i=0; i<urlPieces.length; i++) {
            if(i < urlPieces.length - 2) {          // until the last but one piece
                returnURL += urlPieces[i] + ".";    // reassemble
            } else if(i == urlPieces.length - 2) {  // if it is the last but one piece
                returnURL += urlPieces[i] + "_thumb.";
            } else {
                returnURL += urlPieces[i]
            }
        }
        
        return returnURL;
    }
    
    renderingModes["defaultTopFeeds"] = function(data, extraInfo) {
        var tabLeftArea = createElem("div", {
            id: "tabContentAreaLeft"
        })
        
        if(data.rss.channel.item[0].title) {
            var headingElement = createElem("h2", {});
            if(data.rss.channel.item[0].link) {
                headingElement.appendChild(
                    createElem("a", {
                        href: data.rss.channel.item[0].link,
                        title: data.rss.channel.item[0].title,
                        content: data.rss.channel.item[0].title
                    })
                );
            } else {
                headingElement.appendChild(document.createTextNode(data.rss.channel.item[0].title));
            }
            tabLeftArea.appendChild(headingElement);
        }
        
        if(data.rss.channel.item[0].enclosure) {
            if(data.rss.channel.item[0].link) {
                tabLeftArea.appendChild(
                    createElem("a", {
                        href: data.rss.channel.item[0].link,
                        title: data.rss.channel.item[0].title,
                        content: createElem("img", {
                            id: "mainRSSImage",
                            src: data.rss.channel.item[0].enclosure.url,
                            alt: data.rss.channel.item[0].title
                        })
                    })
                );
            } else {
                tabLeftArea.appendChild(
                    createElem("img", {
                        id: "mainRSSImage",
                        src: data.rss.channel.item[0].enclosure.url,
                        alt: data.rss.channel.item[0].title
                    })
                );
            }
        }
        
        if(data.rss.channel.item[0].description) {
            var topNewsStory = createElem("div", {});
            topNewsStory.innerHTML = data.rss.channel.item[0].description;
            tabLeftArea.appendChild(topNewsStory);
        }

        self.tabContentArea.appendChild(tabLeftArea);
        
        var tabRightArea = createElem("div", {id: "tabContentAreaRight"});
        
        if(data.rss.channel.item[1].enclosure) {
            tabRightArea.appendChild(
                createElem("img", {
                    id: "secondaryRSSImage",
                    src: getThumbnailURL(data.rss.channel.item[1].enclosure.url),
                    alt: data.rss.channel.item[1].title
                })
            );
        }
        
        if(data.rss.channel.item[1].title) {
            if(data.rss.channel.item[1].link) {
                tabRightArea.appendChild(createElem("h2", {
                    content: createElem("a", {
                        href: data.rss.channel.item[1].link,
                        content: data.rss.channel.item[1].title,
                        title: data.rss.channel.item[1].title
                    })
                }));
            } else {
                tabRightArea.appendChild(createElem("h2", {content: data.rss.channel.item[1].title}));
            }
        }
        
        if(data.rss.channel.item[1].description) {
            var secondaryNewsStory = createElem("div", {});
            secondaryNewsStory.innerHTML = data.rss.channel.item[1].description;
            tabRightArea.appendChild(secondaryNewsStory);
        }
        
        tabRightArea.appendChild(createElem("div", {cssClass: "clear"}));
        
        if(data.rss.channel.item.length<6)
            var displayCount = data.rss.channel.item.length;
        else
            var displayCount = 6;

        if(displayCount > 2) {
            tabRightArea.appendChild(createElem("h2", {content: extraInfo}));
            tabRightArea.appendChild(createElem("a", {
                href: self.rssUrl,
                title: "Kings News",
                id: "contentRssLink",
                content: createElem("img", {
                    src: "/media/monarchs/rss-icon.gif",
                    alt: "RSS"
                })
            }));
        
            var newsList = createElem("ul", {id: "newsList"});
            
            for(var i=2; i<displayCount; i++) {
                var pubDate;
                
                if(data.rss.channel.item[i].pubDate)
                    pubDate = createElem("p", {cssClass: "newsDate", content: formatDateShort(data.rss.channel.item[i].pubDate)});
                else
                    pubDate = "";
                
                newsList.appendChild(
                    createElem("li", {
                        content: [
                            pubDate,
                            createElem("a", {
                                href: data.rss.channel.item[i].link,
                                content: data.rss.channel.item[i].title
                            })
                        ]
                    })
                );
            }
            
            tabRightArea.appendChild(newsList);
        }
        
        self.tabContentArea.appendChild(tabRightArea);
        
        var clearingDiv = createElem("div", {
            cssClass: "clear"
        })
        
        clearingDiv.appendChild(document.createTextNode(" "));

        self.tabContentArea.appendChild(clearingDiv);
    }

    renderingModes["defaultBottomFeeds"] = function(data, extraInfo) {
        self.tabContentArea.appendChild(
            createElem("h2", {
                content: self.listItem.getElementsByTagName("span")[0].innerHTML
            })
        );
        
        self.tabContentArea.appendChild(
            createElem("a", {
                href: self.rssUrl,
                title: "Get the RSS Feed",
                id: "bottomRSSLink",
                content: createElem("img", {
                    src: "/media/monarchs/rss-icon.gif",
                    alt: "RSS"
                })
            })
        );

        self.tabContentArea.appendChild(
            createElem("ul", {
                id: "bottomNewsList"
            })
        );
        
        for(var i=0; i<3; i++) {
            if(data.rss.channel.item[i].enclosure) {
                var imageLink = createElem("a", {
                    href: data.rss.channel.item[i].link,
                    title: data.rss.channel.item[i].title,
                    cssClass: "newsThumb",
                    content: createElem("img", {
                        src: getThumbnailURL(data.rss.channel.item[i].enclosure.url),
                        alt: data.rss.channel.item[i].enclosure.title
                    })
                })
            } else {
                var imageLink = "";
            }
            
            $("bottomNewsList").appendChild(
                createElem("li", {
                    content: [
                        imageLink,
                        createElem("h3", {
                            content: createElem("a", {
                                href: data.rss.channel.item[i].link,
                                title: data.rss.channel.item[i].title,
                                content: data.rss.channel.item[i].title
                            })
                        }),
                        createElem("p", {
                            cssClass: "dateTime",
                            content: formatDateLong(data.rss.channel.item[i].pubDate)
                        }),
                        createElem("div", {id: ("rssNewsItem" + i)}),
                        createElem("div", {
                            cssClass: "clear"
                        })
                    ]
                })
            );
            
            $("rssNewsItem" + i).innerHTML = data.rss.channel.item[i].description;
        }
    }
}
