/// <reference path="jquery-1.3.2.js" />
/// <reference path="jquery-extensions.js" />


kark = {};
kark.sharepoint = {};
kark.sharepoint.webpart = {};
kark.sharepoint.webpart.CSS = function() { }

//CSS Class Names

//Container Class for accordion 
//it's the class that gets added on to the table tag of the 
//webpart zone for accordion
kark.sharepoint.webpart.CSS.accordion = "accordion";
//Class for the accordion bar
kark.sharepoint.webpart.CSS.accordionBar = "accordionBar";
//Class for the accordion bar hover
kark.sharepoint.webpart.CSS.accordionBarHover = "accordionBarHover";

//it's the class that gets added on to the table tag of the 
//webpart zone for tabs
kark.sharepoint.webpart.CSS.tabs = "tabs";

//Class for individual tab item
kark.sharepoint.webpart.CSS.tabItem = "tabItem";
//Class for individual selected tab item
kark.sharepoint.webpart.CSS.tabItemSelected = "tabItemSelected";
//Class for the container of tabs. 
//It's the class added to the td that contains the tabs
kark.sharepoint.webpart.CSS.tabItems = "tabItems";
kark.sharepoint.webpart.CSS.tabItemHover = "tabItemHover";

kark.sharepoint.webpart.enums = function() {
    /// <summary>
    /// Defines enum namespace
    /// </summary>
}

//Enums
kark.sharepoint.webpart.enums.TabType = { Tab: 0, Accordion: 1 }

//Static method
kark.sharepoint.webpart.GetWPZone = function(webPartId) {
    /// <summary>
    /// Gets the top level table element for the zone
    /// </summary>

    var scriptTag = $("#" + webPartId + "__Tabs");

    var parentTD = scriptTag.closest("table").parent();

    var wpZone = parentTD.closest("table");

    if (wpZone.length == 0) {
        return null;
    }

    if (wpZone[0].style.visibility != "visible") {
        wpZone.css('visibility', 'hidden');
    }

    return wpZone;

}

kark.sharepoint.webpart.getWPDivs = function(wpzone) {
    /// <summary>
    /// Gets all the webparts in the zone
    /// </summary>

    return wpzone.find(".ms-WPHeader").parent().closest("tr").next().children().children();
}

kark.sharepoint.webpart.TabsBaseClass = function() {
    /// <summary>
    /// Defines a base class for tab and accordion
    /// </summary>

};

kark.sharepoint.webpart.TabsBaseClass.prototype = {
    init: function(webPartId, width, height) {
        /// <summary>
        /// Initializes member vars.
        /// </summary>

        //Set up all the member variables
        this.wpZone = kark.sharepoint.webpart.GetWPZone(webPartId);

        // css class
        this.cssClass = this.tabsZoneCssClass;
        this.itemContainerClass = this.tabItemsCssClass;
        this.itemClass = this.tabItemCssClass;
        this.selectedItemClass = this.selectedtabItemCssClass;
        this.hoverClass = this.tabItemHoverCssClass;
        

        // properties
        this.webPartId = webPartId;
        this.height = height;
        this.width = width;
        //webpartdivs can only be set once the dom has loaded
        //so webpartdivs gets populated in arrange inistead of init
        this.webpartDivs = null;
        this.contentElements = new Array();
        this.tabs = new Array();
        
        //methods
        this.createItem = this.createTab;
        this.createContainer = this.createTabContainer;
        this.getContentElement = this.getElemenetToHide;
        this.showContent = this.showTabContent;
        
    },

    arrange: function() {
        /// <summary>
        /// Arranges webparts in the zone in tabs/accordion style
        /// </summary>

        if (!this.wpZone) {
            return;
        }


        //Hide the unwanted spacing elements
        this.wpZone.find("div[class*='ms-PartSpacing']").hide();

        // See if we have container that all tabs needs to be wrapped into
        var tabContainer = this.createContainer();

        if (tabContainer != null && tabContainer.length == 1) {
            // set the class on tab container if one exists
            tabContainer.addClass(this.itemContainerClass);
        }

        var counter = 0;

        //get all the webpart divs in the zone
        this.webpartDivs = kark.sharepoint.webpart.getWPDivs(this.wpZone);

        //set height and width
        this.setDimensions(this.height, this.width);

        //go through each webpart and arrange it
        for (var i = 0; i < this.webpartDivs.length; i++) {

            var wpDiv = $(this.webpartDivs[i]);
            
            // only arrange it if it is not hidden
            if (wpDiv.closest("table")[0].style.display != "none") {

                //get the title TD
                var partId = wpDiv[0].id.replace("WebPart", "");
                    
                var titleTd = this.wpZone.find("#WebPartTitle" + partId);
                
                //if it has title than only arrange it
                if (titleTd.length > 0) {

                    var title = kark.sharepoint.webpart.TabsBaseClass.prototype.parseTitle(titleTd);
                    //create a tab item
                    var tabItem = this.createItem(titleTd, title.text);
                    
                    //set the css class
                    tabItem.addClass(this.itemClass);

                    //bind the click event
                    tabItem.bind("click", { tabIndex: counter}, this.toggle.bind(this));

                    //bind onmouseout and onmouseover for hover
                    tabItem.bind("mouseover", { tabIndex: counter }, this.hover.bind(this));
                    tabItem.bind("mouseout", { tabIndex: counter }, this.hover.bind(this));

                    // get the content element for the webpart
                    var contentElement = this.getContentElement(wpDiv[0].id);

                    //figure out if a tab item is the first one, if it is than
                    //it is the default item and needs to be selected
                    //////////////****************************************************
                    if (i == 0 && this.webpartDivs.length<4) {

                        if (this.selectedItemClass && this.selectedItemClass != null) {
                            tabItem.addClass(this.selectedItemClass);
                        }
                    } 
                    else if (i == 4 && this.webpartDivs.length>3) {

                        if (this.selectedItemClass && this.selectedItemClass != null) {
                            tabItem.addClass(this.selectedItemClass);
                        }
                    } 
                    else {

                        contentElement.hide();
                    }

                    // add the tabitem to container if one is available
                    if (tabContainer != null && tabContainer.length == 1) {
                        tabContainer.append(tabItem);
                    }

                    //save the content element into array so it can be used to show the element when
                    // related tab is clicked
                    this.contentElements[counter] = contentElement;

                    //save the ref to the tab in an array which will later used in toggle method
                    this.tabs[counter] = tabItem;

                    counter++;
                }

            }

        }

        this.wpZone.addClass(this.cssClass);
        this.wpZone.css('visibility', 'visible')

    },

    toggle: function(e) {
        /// <summary>
        /// Shows the tab/accordion that was clicked by user and hides the rest
        /// </summary>

        if (this.wpZone[0].id != "MSOZone") {

            var tabIndex = e.data.tabIndex;

            if (this.tabs[tabIndex] != null && this.tabs[tabIndex].length > 0) {

                // hide all of the other contents
                for (var i = 0; i < this.contentElements.length; i++) {
                    if (i != tabIndex) {

                        this.contentElements[i].hide();

                        //remove the selected itemclass
                        if (this.tabs[i].hasClass(this.selectedItemClass)) {
                            this.tabs[i].removeClass(this.selectedItemClass);
                        }
                    } else {
                        // add selectedItemClass for selected tab
                        this.tabs[i].addClass(this.selectedItemClass);
                    }
                }

                // call showcontent virtual method
                this.showContent(e.data);
            }
        }
    },

    hover: function(e) {
        /// <summary>
        /// Shows hover animation on tabs
        /// </summary>

        var tabIndex = e.data.tabIndex;
        if (this.tabs[tabIndex] != null && this.tabs[tabIndex].length > 0) {
            this.tabs[tabIndex].toggleClass(this.hoverClass);
        }

    },

    parseTitle: function(titleTd) {
        /// <summary>
        /// Helper method to extract title and title url from the Title td
        /// </summary>

        var titleText = titleTd.find("span").text();
        var a = titleTd.find("a");
        var href = null;
        if (a != null && a.length > 0) {
            href = a.attr("href");
        }

        var title = new Object();
        title.text = titleText;
        title.href = href;
        return title;
    },

    setDimensions: function(height, width) {
        /// <summary>
        /// Sets the height and width on the top level table and on each web part div
        /// </summary>


        if (width && width != null) {

            // Set width of zone container 
            this.wpZone.css("width", width);

            // Set height and width of web parts in the zone.
            this.webpartDivs.css("width", width);
            this.webpartDivs.css("overflow", "auto");

            if (height && height != null) {
                this.webpartDivs.css("height", height);
            }
        }
    }
}

kark.sharepoint.webpart.tabs = function() { };

kark.sharepoint.webpart.tabs.prototype = {

    // Just calling to base class methods
    init: kark.sharepoint.webpart.TabsBaseClass.prototype.init,
    arrange: kark.sharepoint.webpart.TabsBaseClass.prototype.arrange,
    toggle: kark.sharepoint.webpart.TabsBaseClass.prototype.toggle,
    hover: kark.sharepoint.webpart.TabsBaseClass.prototype.hover,
    setDimensions: kark.sharepoint.webpart.TabsBaseClass.prototype.setDimensions,

    //Virtual properties

    ///CSS class for tab zone
    tabsZoneCssClass: kark.sharepoint.webpart.CSS.tabs,

    ///CSS class for each Tab item
    tabItemCssClass: kark.sharepoint.webpart.CSS.tabItem,

    ///CSS class for selected tab
    selectedtabItemCssClass: kark.sharepoint.webpart.CSS.tabItemSelected,

    ///CSS class for the container of tab item
    tabItemsCssClass: kark.sharepoint.webpart.CSS.tabItems,

    ///CSS class for hover
    tabItemHoverCssClass: kark.sharepoint.webpart.CSS.tabItemHover,

    
    //Virtual methods

    ///createItem is called to create individual tab item
    createTab: function(titleTD, titleText) {
        titleTD.parent().hide();
        return $("<span><span>" + titleText + "</span></span>");
    },

    ///CreateContainer is called to create a container for tab items
    createTabContainer: function() {

        //create an empty TR and append it after last tr of the table
        //that will give tabs at the bottom
        var tabTr = "<tr></tr><tr><td id='portalv2Tabs'></td></tr>";
        var tBody = this.wpZone.children("tbody");
        var firstTr = tBody.children("tr:first");
        firstTr.before(tabTr);

        
        //only return the <td> portion so individual tab items can be appended
        // to td
        return this.wpZone.find("#portalv2Tabs");

    },

    /// returns the tab content element that needs to be hidden
    getElemenetToHide: function(tabId) {
        return $("#MSOZoneCell_" + tabId).parent();
    },

    showTabContent: function(tabData) {

        this.contentElements[tabData.tabIndex].show();

    }

    
}

kark.sharepoint.webpart.accordion = function() { };

kark.sharepoint.webpart.accordion.prototype = {

    // Just calling to base class methods
    init: kark.sharepoint.webpart.TabsBaseClass.prototype.init,
    arrange: kark.sharepoint.webpart.TabsBaseClass.prototype.arrange,
    toggle: kark.sharepoint.webpart.TabsBaseClass.prototype.toggle,
    hover: kark.sharepoint.webpart.TabsBaseClass.prototype.hover,
    setDimensions: kark.sharepoint.webpart.TabsBaseClass.prototype.setDimensions,

    //Virtual properties

    ///CSS class for tab zone
    tabsZoneCssClass: kark.sharepoint.webpart.CSS.accordion,

    ///CSS class for each Tab item
    tabItemCssClass: kark.sharepoint.webpart.CSS.accordionBar,

    ///CSS class for hover
    tabItemHoverCssClass: kark.sharepoint.webpart.CSS.accordionBarHover,

    //Virtual methods

    ///createItem is called to create individual tab item
    createTab: function(titleTD, titleText) {
        // we need to replace the html of titleTD with our own and than return the titleTD
        var html = "<td><span>" + titleText + "</span></td>";
        var tr = titleTD.parent();
        tr.html(html)
        return tr.find("td");
    },

    /// No need of conatiner for accordion
    createTabContainer: function() {
        return null;
    },

    /// returns the tab content element that needs to be hidden
    getElemenetToHide: function(tabId) {
        return $("#" + tabId);
    },

    showTabContent: function(tabData) {
        this.contentElements[tabData.tabIndex].slideDown();
    }

    
}


function BuildKarkTabs(webPartId, tabType, width, height) {
    

    var tabs = null;
    
    if (tabType == kark.sharepoint.webpart.enums.TabType.Tab) {
        tabs = new kark.sharepoint.webpart.tabs();
    } else {
        tabs = new kark.sharepoint.webpart.accordion();
    }
    
    tabs.init(webPartId, width, height);
    $(document).ready(function() {
        tabs.arrange();
    });
}    
