// Copyright 2012-2013 Adobe Systems Incorporated.  All rights reserved.

//--------------------------------------------------------------------
// CLASS:
//   JQuery.DesignTime.Widget.Tabs
//
// DESCRIPTION:
//   This class is used by the Tabs property inspector to manage
//   and manipulate the design-time state of the widget's markup in the
//   design view.

//Global variables----------------------------------------------------
  var tabIdString = "tabs-";
  var notInDomIdArray = [];
//--------------------------------------------------------------------
  
//--------------------------------------------------------------------
// FUNCTION:
//   Tabs
//
// DESCRIPTION:
//   Constructor function for the design-time object that manages the state of
//   the Tabs widget markup in the design view. This constructor
//   is registered in the JQuery Widget translator found at:
//
//       Configuration/Translators/JQueryWidget.htm
//
//   and will automatically be invoked for any tabbed panels markup on the
//   page.
//
// ARGUMENTS:
//   dom - object - The DOM used by the document in design view.
//   element - object - The top-level DOM element for our widget markup.
//   
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs = function(dom, element, consArgs)
{
  JQuery.DesignTime.Widget.Base.call(this, dom, element);
	this.opts = {};
	this.opts = consArgs;
	this.eventArray = [];
  this.tabBarClass = "ui-tabs ui-widget-content";
  this.tabGroupClass = "ui-tabs-nav ui-helper-clearfix ui-widget-header";
  this.tabGroupStyle = "height:40px";
  this.inactiveTabClass = "ui-state-default ui-corner-top";
  this.inactiveTabStyle = "width:100px; height:37px";
  this.tabSelectedClass = "ui-state-active";
  this.tabSelectedStyle = "width:100px; height:38px";
  this.panelVisibleClass = "ui-tabs-panel ui-widget-content ui-corner-bottom";
  this.defaultTabId = this.getDefaultTab() ;
  this.currentTabIndex = this.defaultTabId;
	this.initEventArray();
	this.heightStyleArray = [];
	this.initHeightStyleArray();
	this.animationArray = [];
	this.initAnimationArray();
	this.orientationArray = [];
	this.initOrientationArray();
  this.attachBehaviors();
  this.addDwEditingAttributes();
  this.canRefresh = true;
}; 

// JQuery.DesignTime.Widget.TabbedPanels derives from our JQuery.DesignTime.Widget.Base
// class, so create a Base object and use it as our prototype so we inherit all of its
// methods.

JQuery.DesignTime.Widget.Tabs.prototype = new JQuery.DesignTime.Widget.Base();

// Reset the constructor property back to Tabs for our newly created prototype
// object so callers know that our object was created with the Tabs constructor.
JQuery.DesignTime.Widget.Tabs.prototype.constructor = JQuery.DesignTime.Widget.Tabs;

//--------------------------------------------------------------------
// FUNCTION:
//   getAssets
//
// DESCRIPTION:
//   Static function that returns the assets to be applied to page
//
// ARGUMENTS:
//   None
//
// RETURNS:
//   (array of objects)
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.getAssets = function()
{
	var assets = new Array();
	
	assetObject = new Object();
	assetObject.fullPath = jQTabImagesPath;
	assetObject.file = jQTabImagesFile;
	assetObject.type = "";
	assets.push(assetObject);
	
	assetObject = new Object();
	assetObject.fullPath = jQCoreCssPath;
	assetObject.file = jQCoreCssFile;
	assetObject.type = "link";
	assets.push(assetObject);

	assetObject = new Object();
	assetObject.fullPath = jQCssThemePath;
	assetObject.file = jQCssThemeFile;
	assetObject.type = "link";
	assets.push(assetObject);
	
	assetObject = new Object();
	assetObject.fullPath = jQTabCssWidgetPath;
	assetObject.file = jQTabCssWidgetFile;
	assetObject.type = "link";
	assets.push(assetObject);
	
	assetObject = new Object();
	assetObject.fullPath = jQMainPath;
	assetObject.file = jQMainFile;
	assetObject.type = "javascript";
	assets.push(assetObject);
	
	assetObject = new Object();
	assetObject.fullPath = jQTabJsPath;
	assetObject.file = jQTabJsFile;
	assetObject.type = "javascript";
	assets.push(assetObject);
	
	return (assets);
};

JQuery.DesignTime.Widget.Tabs.prototype.recalculateOpts = function()
{
	this.opts = {};
	var consArgs = this.getConstructorArgs(this.widgetType);
	this.opts = consArgs;
}

//--------------------------------------------------------------------
// FUNCTION:
//   refresh
//
// DESCRIPTION:
//   Syncs up the internal state of the design-time widget object
//   with the markup and constructor snippet that currently exists
//   in the design view.
//
//   This method gets called from the translator if a design-time
//   object already exists for a specific widget ID, and from various
//   methods in the Tabs property inspector.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.refresh = function()
{
  if (!this.canRefresh)
		return;
	
  this.ensureValidElements();
	this.opts = {};
	var consArgs = this.getConstructorArgs(this.widgetType);
	this.opts = consArgs;
  this.defaultTabId = this.getDefaultTab() ;

  // Attach any behaviors and translated attributes to the
  // widget elements in case some new elements were added.
  this.attachBehaviors();
  this.addDwEditingAttributes();
};

//--------------------------------------------------------------------
// FUNCTION:
//   addNoSplitAttr
//
// DESCRIPTION:
//   Internal utility function used to set translated attributes
//   on an element, and conditionally on its children, to prevent
//   Dreamweaver from splitting the element when the user hits
//   the return key.
//
//   These attributes are added to the Tab buttons of the Tabs
//   widget. Since the Tab buttons are <li> elements, we want to prevent
//   Dreamweaver from inserting a new <li> if the user ever hits return.
//   Instead, we tell Dreamweaver to insert a <br>.
//
// ARGUMENTS:
//  ele - object - The DOM element to set the translated attributes on.
//  useBR - boolean - If true tell DW to insert a <br> when the return key is hit.
//  addToChildren - boolean - If true, the function recursively traverses down
//                            the element's child sub-trees adding the translated
//                            attributes to each element.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.addNoSplitAttr = function(ele, useBR, addToChildren)
{
  if (!ele || ele.nodeType != 1 /* ELEMENT_NODE */)
    return;

  ele.setTranslatedAttribute("dwedit:nosplit", "nosplit");

  if (useBR)
    ele.setTranslatedAttribute("dwedit:usebr", "usebr");

  if (addToChildren)
  {
    if (ele.hasChildNodes())
    {
      var child = ele.firstChild;
      while (child)
      {
        if (child.nodeType == 1 /* ELEMENT_NODE */)
          this.addNoSplitAttr(child, useBR, addToChildren);
        child = child.nextSibling;
      }
    }
  }
}; 

//--------------------------------------------------------------------
// FUNCTION:
//   addDwEditingAttributes
//
// DESCRIPTION:
//   Iterates over all the tab buttons in the Tabs widget
//   to add translated attributes that prevent them from being split
//   when the user hits the return key when editing the tab button
//   content.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.addDwEditingAttributes = function()
{
  // If the user hits the return key while the caret is in a
  // tab, we want to prevent the list item handling code from automatically
  // splitting our tab since it will cause a broken widget structure.
  // Instead, just insert a br. We prevent the auto-splitting behavior from
  // occurring by adding the nosplit attribute to the tab element and all
  // of its child elements.

  var tabs = this.getTabs();
  for(var i = 0; i < tabs.length ; i++ )
  {
    var ele = tabs[i];
    if(ele)
      this.addNoSplitAttr(ele, true, true);
  }
};

//--------------------------------------------------------------------
// FUNCTION:
//   getCurrentPanelIndex
//
// DESCRIPTION:
//   Returns the index of the tab panel that is currently showing.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getCurrentPanelIndex = function()
{
  return this.currentTabIndex;
};

//--------------------------------------------------------------------
// FUNCTION:
//   getTabGroup
//
// DESCRIPTION:
//   Returns the DOM element that is the container that holds all
//   of the tab buttons.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   DOM element object or null.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getTabGroup = function()
{
  this.ensureValidElements();
  if (this.element)
  {
    var children = this.getElementChildren(this.element);
    if (children.length && children[0].tagName.toLowerCase() == "ul")
      return children[0];
  }
  return null;
};

//--------------------------------------------------------------------
// FUNCTION:
//   getTabs
//
// DESCRIPTION:
//   Returns an array containing all of the tab button elements. 
//   This function always returns an array. If the tab group element
//   is missing, or contains no tab button elements, the array returned
//   will contain no elements and have a length of zero.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   Array of tab button elements.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getTabs = function()
{
  var tabs = [];
  var tg = this.getTabGroup();
  if (tg)
    tabs = this.getElementChildren(tg);
  return tabs;
};

//--------------------------------------------------------------------
// FUNCTION:
//   getContentPanels
//
// DESCRIPTION:
//   Returns an array containing all of the tab content panel elements. 
//   This function always returns an array. 
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   Array of tab content panel elements.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getContentPanels = function()
{
  var panels = [];
  this.ensureValidElements();
  
  panels = this.getElementChildren(this.element);
  panels.shift();
  
  return panels;
};

//--------------------------------------------------------------------
// FUNCTION:
//   onDWContextButtonActivate
//
// DESCRIPTION:
//   Internal event callback function for handling the click on the
//   activate button that appears in tab buttons in design view.
//   Clicking on this button in design view causes the corresponding
//   tab panel to show.
//
// ARGUMENTS:
//   tab - object - The tab button element.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.onDWContextButtonActivate = function(tab)
{
	dw.logEvent(UT_JQUERY_TABS, UT_JQUERY_TABS_OPEN_TAB);

  // Treat context button activate event the same as a click.
  this.showPanel(tab);
};

//--------------------------------------------------------------------
// FUNCTION:
//   addPanelEventListeners
//
// DESCRIPTION:
//   Internal function that adds event handlers to the elements that
//   make up a single tab panel. These event handlers are meant to be
//   triggered from events generated by the user when interacting with
//   the widget in design view.
//
//   Currently, only tab buttons have event handlers on them.
//
// ARGUMENTS:
//  tab - object - The tab button DOM element.
//  panel - object - The tab content panel DOM element.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.addPanelEventListeners = function(tab, panel)
{
  var self = this;
  this.addEventListener(tab, "DWContextButtonActivate", function(e) { return self.onDWContextButtonActivate(tab); }, false);
};

//--------------------------------------------------------------------
// FUNCTION:
//   getIndex
//
// DESCRIPTION:
//   Internal utility function that returns the index of the specified
//   element in the specified array.
//
// ARGUMENTS:
//  ele - object - DOM element object.
//  arr - array - Array of DOM element objects.
//
// RETURNS:
//   The index of ele in arr, or -1 if not found.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getIndex = function(ele, arr)
{
  ele = this.getElement(ele);
  if (ele && arr && arr.length)
  {
    for (var i = 0; i < arr.length; i++)
    {
      if (ele == arr[i])
        return i;
    }
  }
  return -1;
};

//--------------------------------------------------------------------
// FUNCTION:
//   getTabbedPanelIndex
//
// DESCRIPTION:
//   Utility function for getting the tab panel index for a given
//   tab button or tab content panel element.
//
// ARGUMENTS:
//  ele - object - DOM element that is either the tab button or tab
//                 content panel.
//
// RETURNS:
//   The index of the tab panel, or -1 if not found.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getTabbedPanelIndex = function(ele)
{
  // Check if ele is in our list of tabs.
  var i = this.getIndex(ele, this.getTabs());
  if (i < 0)
  {
    // ele wasn't in our list of tabs so now check
    // through our list of content panels.
    i = this.getIndex(ele, this.getContentPanels());
  }
  return i;
};

//--------------------------------------------------------------------
// FUNCTION:
//   getMinTabbedPanelCount
//
// DESCRIPTION:
//   Returns the number of tab panels in the widget.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   Returns the number of tab panels in the widget, or zero if the
//   widget contains no tab panels.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getMinTabbedPanelCount = function()
{
  return Math.min(this.getTabs().length, this.getContentPanels().length);
};

//--------------------------------------------------------------------
// FUNCTION:
//   showPanel
//
// DESCRIPTION:
//   Shows the tab panel specified by the given index, tab button
//   DOM element, or tab button panel DOM element.
//
// ARGUMENTS:
//  ele - integer or object - Index of the tab panel to show, or the
//                            tab button or tab content panel element
//                            of the tab panel to show.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.showPanel = function(elementOrIndex)
{
  this.ensureValidElements();
  var tpIndex = -1;
  
  if (typeof elementOrIndex == "number")
    tpIndex = elementOrIndex;
  else // Must be the element for the tab or content panel.
    tpIndex = this.getTabbedPanelIndex(elementOrIndex);
  
  var numTabbedPanels = this.getMinTabbedPanelCount();

  if (tpIndex < 0 || tpIndex >= numTabbedPanels)
  {
    if (this.currentTabIndex >= 0 && this.currentTabIndex < numTabbedPanels)
      tpIndex = this.currentTabIndex;
    else if (tpIndex <= 0)
      tpIndex = 0;
    else // tpIndex >= nunmTabbedPanels
      tpIndex = numTabbedPanels - 1;
  }

  var tabs = this.getTabs();
  var panels = this.getContentPanels();

  numTabbedPanels = Math.max(tabs.length, panels.length);

  for (var i = 0; i < numTabbedPanels; i++)
  {
    if (i != tpIndex)
    {
      if (tabs[i])
      {
        this.removeClassName(tabs[i], this.tabSelectedClass);
		this.addClassName(tabs[i], this.inactiveTabClass);
        this.addStyleForWidget(tabs[i], this.inactiveTabStyle);
		
        // Add the dw show button to the closed tab.
        if( this.isValidPanelStructure(i) )
        {
          this.addShowPanelContextButton(tabs[i]);
        }
      }
      
      if (panels[i])
      {
        this.removeClassName(panels[i], this.panelVisibleClass);
        panels[i].translatedStyle.display = "none";
      }
    }
	
	
  }

  this.currentTabIndex = tpIndex;
  if (tabs[tpIndex])
  {
	this.removeClassName(tabs[tpIndex], this.inactiveTabClass);
    this.addClassName(tabs[tpIndex], this.tabSelectedClass);
	this.addStyleForWidget(tabs[tpIndex], this.tabSelectedStyle);
    
    // Remove the dw show button from the panel that's now open.
    this.removeContextButton(tabs[tpIndex]);
  }
  
  if (panels[tpIndex])
  {
    this.addClassName(panels[tpIndex], this.panelVisibleClass);
    panels[tpIndex].translatedStyle.display = "block";
  }
};

//--------------------------------------------------------------------
// FUNCTION:
//   attachBehaviors
//
// DESCRIPTION:
//   Internal utility function for attaching event handlers to all
//   tab panels and setting the initial display state of the widget.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.attachBehaviors = function()
{
  if (!this.isWidgetStructureValid())
	return;

  var tabs = this.getTabs();
  var panels = this.getContentPanels();
  var panelCount = this.getMinTabbedPanelCount();

  this.ensureValidElements();
  this.addClassName(this.element, this.tabBarClass);
  var tabGroup = this.getTabGroup();
  this.addClassName(tabGroup, this.tabGroupClass);
  this.addStyleForWidget(tabGroup, this.tabGroupStyle);
  
  for (var i = 0; i < panelCount; i++)
    this.addPanelEventListeners(tabs[i], panels[i]);

  this.showPanel(this.currentTabIndex);
};

//--------------------------------------------------------------------
// FUNCTION:
//   isWidgetStructureValid
//
// DESCRIPTION:
//   Traverses the widget markup structure and checks to see if
//   it contains the correct nesting and number of elements.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   true if widget structure is valid, or false if it is invalid.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.isWidgetStructureValid = function()
{
  var ele = this.element;
  if( !ele || !ele.hasChildNodes )
    return false;

  // Make sure that we have matching pairs of tabs and content
  // panels.

  var numTabs = this.getTabs().length;
  var numPanels = this.getContentPanels().length;

  if (numTabs != numPanels)
	return false;

  for( var i=0; i<numTabs; i++ )
  {
	if (!this.isValidPanelStructure(i))
	{
		return false;
	}
  }
  
  return true;
  
};

//--------------------------------------------------------------------
// FUNCTION:
//   isValidPanelStructure
//
// DESCRIPTION:
//   Makes sure that a tab button and tab content panel exists
//   for the tab panel with the specified index.
//
// ARGUMENTS:
//  panelIndex - integer - The index of the tab panel to validate.
//
// RETURNS:
//   true if panel is valid and false if it is invalid.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.isValidPanelStructure = function(panelIndex)
{
  var tab = this.getTabs()[panelIndex]; 
  var panel = this.getContentPanels()[panelIndex];
  
  if( !tab || !JQuery.DesignTime.Widget.Tabs.isValidTab(tab) || !panel || !JQuery.DesignTime.Widget.Tabs.isValidPanel(panel) )
		return false;
	
  return true;
};

//--------------------------------------------------------------------
// FUNCTION:
//   setDefaultTab
//
// DESCRIPTION:
//   Adds the defaultTab option to the constructor snippet in the
//   document.
//
// ARGUMENTS:
//  defaultTabIndex - integer - The index of the tab panel to show by default.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.setDefaultValue = function(defaultValue)
{
	if( defaultValue == null || typeof defaultValue == "undefined" )
		return;
		
	if (!this.opts)
		this.opts = {};
		
	var oldDefaultValue = this.opts.selected;
		
	if( defaultValue == "" || defaultValue.toString() == '0' || parseInt(defaultValue).toString() == 'NaN' )
	{
		this.opts.selected = null;
	}	
	else
	{
		this.opts.selected = parseInt(defaultValue);
	}
	
	if( oldDefaultValue != this.opts.selected )
		this.updateOptions(this.widgetType, this.opts);
};
JQuery.DesignTime.Widget.Tabs.prototype.setCollapsibleValue = function(collapsibleValue)
{
	if( collapsibleValue == null || typeof collapsibleValue == "undefined" )
		return;

	if (!this.opts)
		this.opts = {};	
		
	if( collapsibleValue == true )
	{
		this.opts.collapsible = true;
	}	
	else
	{
		this.opts.collapsible = null;
	}
	
	this.updateOptions(this.widgetType, this.opts);
};
JQuery.DesignTime.Widget.Tabs.prototype.setEvent = function(eventIndex)
{
	if (!this.opts)
		this.opts = {};
	
	var oldEventValue = this.opts.event;
	
	if( eventIndex == 0 )
		this.opts.event = null;
	else
		this.opts.event = this.getEventOptions()[eventIndex];
	
	if( oldEventValue != this.opts.event )
		this.updateOptions(this.widgetType, this.opts);
};

//--------------------------------------------------------------------
// FUNCTION:
//   getDefaultTab
//
// DESCRIPTION:
//   Returns the index of the tab panel that will show by default
//   when the document is loaded into the browser.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   The index of the default tab panel or zero if it is not specified
//   in the widget's constructor snippet.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getDefaultTab = function()
{
  return (this.opts && this.opts.selected && typeof this.opts.selected != 'undefined')? this.opts.selected : 0;
};
JQuery.DesignTime.Widget.Tabs.prototype.getCollapsibleValue = function()
{
	if( this.opts && this.opts.collapsible != null && typeof this.opts.collapsible != 'undefined' )
	{
		return (this.opts.collapsible == true);
	}
	return false;
};
JQuery.DesignTime.Widget.Tabs.prototype.getEventIndex = function()
{
  if( this.opts && this.opts.event != null && typeof this.opts.event != 'undefined' )
	{
		var eventArray = this.getEventOptions();
		for( var i = 0; i < eventArray.length; i++ )
		{
			if( this.opts.event == eventArray[i] )
				return i;
		}
		return 0;
	}
	return 0;
};


JQuery.DesignTime.Widget.Tabs.isValidTab = function(tabEle)
{
	return (tabEle.tagName.toLowerCase() == "li");
}

JQuery.DesignTime.Widget.Tabs.isValidPanel = function(panelElement)
{
	return (panelElement.tagName.toLowerCase() == "div");
}

JQuery.DesignTime.Widget.Tabs.prototype.initEventArray = function()
{
	this.eventArray.push("click");
	this.eventArray.push("mouseover");
}

//--------------------------------------------------------------------
// FUNCTION:
//   movePanelUp
//
// DESCRIPTION:
//   Moves the tab panel at the current index to the index-1 position.
//   Does nothing if the specified index is zero.
//
// ARGUMENTS:
//  panelIndex - integer - Index of the tab panel to move.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.movePanelUp = function(panelIndex)
{
  var tabs = this.getTabs();
  var numTabs = tabs.length;

  if (panelIndex < 1 || numTabs < 2 || panelIndex >= tabs.length)
    return;

  var panels = this.getContentPanels();

  var prevTab = tabs[panelIndex - 1];
  var prevPanel = panels[panelIndex - 1];

  var tab = tabs[panelIndex];
  var panel = panels[panelIndex];

  if (!prevTab || !prevPanel || !tab || !panel)
    return;

  this.canRefresh = false;
  prevTab.outerHTML = tab.outerHTML + prevTab.outerHTML;
  tab.outerHTML = "";

  prevPanel.outerHTML = panel.outerHTML + prevPanel.outerHTML;
  panel.outerHTML = "";
  this.canRefresh = true;
};

//--------------------------------------------------------------------
// FUNCTION:
//   movePanelDown
//
// DESCRIPTION:
//   Moves the tab panel at the current index to the index+1 position
//   within the widget. Does nothing if the specified index is for the
//   last tab panel in the widget.
//
// ARGUMENTS:
//  panelIndex - integer - Index of the tab panel to move.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.movePanelDown = function(panelIndex)
{
  this.movePanelUp(panelIndex + 1);
};

//--------------------------------------------------------------------
// FUNCTION:
//   addPanel
//
// DESCRIPTION:
//   Adds a new tab panel after the tab panel specified by prevIndex.
//
// ARGUMENTS:
//  prevIndex - integer - The index of the tab panel to insert the new
//                        panel after.
//  label - string - The content to insert into the new tab button
//                   after it is created.
//  content - string - The content to insert into the new tab content
//                     panel after it is created.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.addPanel = function(prevIndex, label, content)
{
  var counter = 1;
  var tabs = this.getTabs();
  if( tabs && tabs.length )
    counter = tabs.length + 1;
  
  var tabId = JQuery.DesignTime.Widget.Tabs.getNewTabId();
  var tStr = JQuery.DesignTime.Widget.Tabs.getTabMarkupSnippet(label, counter, tabId);
  var pStr = JQuery.DesignTime.Widget.Tabs.getPanelMarkupSnippet(content, counter, tabId);
  var prevTab = this.getTabs()[prevIndex];
  var prevPanel = this.getContentPanels()[prevIndex];

  if (!prevTab || !prevPanel)
    return;

  prevTab.outerHTML = prevTab.outerHTML + tStr;
  prevPanel.outerHTML = prevPanel.outerHTML + pStr;
};

//--------------------------------------------------------------------
// FUNCTION:
//   removePanel
//
// DESCRIPTION:
//   Removes the tab panel at the specifed index.
//
// ARGUMENTS:
//  panelIndex - integer - The index of the panel to be removed.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.removePanel = function(panelIndex)
{
  var tab = this.getTabs()[panelIndex];
  if (tab)
    tab.outerHTML = "";

  var panel = this.getContentPanels()[panelIndex];
  if (panel)
    panel.outerHTML = "";
};

//--------------------------------------------------------------------
// FUNCTION:
//   repairTabGroupIfNeeded
//
// DESCRIPTION:
//   Inspects the widget markup structure and adds a tab group
//   container or content panel group container if it is missing.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.repairTabGroupIfNeeded = function()
{
  var tabGroup = this.getTabGroup();

  if (tabGroup)
    return;

  var tgStr = JQuery.DesignTime.Widget.Tabs.getTabGroupMarkupSnippet();
  
  this.ensureValidElements();
  this.element.innerHTML = tgStr + this.element.innerHTML;
};

//--------------------------------------------------------------------
// FUNCTION:
//   getMarkupSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string containing the
//   markup for a complete TabbbedPanels widget.
//
// ARGUMENTS:
//  id - string - The value for the widget's id attribute.
//  label - string - The content to insert into each tab button.
//  content - string - The content to insert into each content panel.
//
// RETURNS:
//   String that is the HTML markup fragment for the widget.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.getMarkupSnippet = function(id, label, content)
{
  var numTabs = 3;
  var str = "<div id=\"" + id + "\"><ul>";
  
 
  for (var i = 0; i < numTabs; i++)
	notInDomIdArray[i] = JQuery.DesignTime.Widget.Tabs.getNewTabId();
  
  for (var i = 0; i < numTabs; i++)
    str += JQuery.DesignTime.Widget.Tabs.getTabMarkupSnippet(label, i+1, notInDomIdArray[i]);

  str += "</ul>";

  for (var i = 0; i < numTabs; i++)
    str += JQuery.DesignTime.Widget.Tabs.getPanelMarkupSnippet(content, i+1, notInDomIdArray[i]);

  str += "</div>";
  notInDomIdArray = [];
  return str;
};

//--------------------------------------------------------------------
// FUNCTION:
//   getConstructorSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string that contains the
//   constructor snippet for creating a widget with the specified id.
//
// ARGUMENTS:
//  id - string - The id of the widget markup to insert into the
//                constructor snippet.
//
// RETURNS:
//   String containing JS that is the constructor call to create the
//   widget.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.getConstructorSnippet = function(id)
{
  return '$(function() {\n\t$( "#' + id + '" ).tabs(); \n});';
  /*
  $(function() {
		$( "#tabs" ).tabs();
	});
  */
};

//--------------------------------------------------------------------
// FUNCTION:
//   getTabGroupMarkupSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string that contains the
//   markup for a tab group container.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   String containing an HTML fragment.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.getTabGroupMarkupSnippet = function()
{
  return "<ul></ul>";
};


//--------------------------------------------------------------------
// FUNCTION:
//   getTabMarkupSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string that contains the
//   markup for a tab button.
//
// ARGUMENTS:
//  label - string - The content to be inserted into the tab button.
//  counter - integer - Optional argument. If specified, is an integer
//                      to append to the label to help differenciate
//                      tab buttons when they all have the same label.
//	tabId - String - Id of the content div to be referred
//
// RETURNS:
//   String that is the HTML fragment for a tab button.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.getTabMarkupSnippet = function(label, counter, tabId)
{
  if( typeof counter == 'undefined' ) counter = "";
  if( typeof tabId == 'undefined') tabId = tabIdString + counter;
  if( typeof label == 'undefined' ) label = dw.loadString('jquery/widgets/tabbedpanels/newSnippet/label'); 
  return "<li><a href=\"#" + tabId + "\">" + label + " " + counter + "</a></li>";
};

//--------------------------------------------------------------------
// FUNCTION:
//   getPanelMarkupSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string that contains the
//   markup for a tab content panel.
//
// ARGUMENTS:
//  content - string - The content to be inserted into the tab content panel.
//  counter - integer - Optional argument. If specified, is an integer
//                      to append to the content to help differenciate
//                      tabs when they all have the same content.
//	tabId - string - Id of the div to be created
//
// RETURNS:
//   String that is the HTML fragment for a tab content.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.getPanelMarkupSnippet = function(content, counter, tabId)
{
  if( typeof counter == 'undefined' ) counter = "";
  if( typeof tabId == 'undefined') tabId = tabIdString + counter;
  if( typeof content == 'undefined' ) content = dw.loadString('jquery/widgets/tabbedpanels/newSnippet/content'); 
  return "<div id=\"" + tabId + "\"><p>" + content + " " + counter + "</p></div>";
};

JQuery.DesignTime.Widget.Tabs.getNewTabId = function ()
{
  var dom = dw.getDocumentDOM();
  var idElems = dom.body.getElementsByAttributeName("id");
  var suffix = 1;
  var newName = tabIdString + suffix;
  var inDomIdArray = [];
  
  for (var i=0; i < idElems.length; i++)
  {
    currId = idElems[i].getAttribute("id");
    if (currId)
      inDomIdArray.push(currId);
  }

	while((dwscripts.findInArray(inDomIdArray, newName) != -1)|| (dwscripts.findInArray(notInDomIdArray, newName) != -1))
	{
		suffix++;
		newName = tabIdString + suffix;
	}


  return newName; 
  
}

JQuery.DesignTime.Widget.Tabs.prototype.getEventOptions = function ()
{
	return this.eventArray;
}
JQuery.DesignTime.Widget.Tabs.getInsertWidgetCallback = function(constructorJs, widgetId)
{
	return function(e)
	{
		var targetDom = e.target.ownerDocument;	
		var newId = e.target.id;
		var newConJs = constructorJs;

		var assetList = new Array();

		//id got renamed on paste, update our constructor
		if( newId && newId != widgetId )
		{
			newConJs = newConJs.replace( widgetId, newId, "gm" );
			
			var newTab = targetDom.getElementById(newId);
			var panels = newTab.getElementsByTagName('div');
			var tabRefs = newTab.getElementsByTagName('a');
				
			if( !tabRefs || !panels || panels.length != tabRefs.length )
			{
				if (dw.isDebugBuild)
				{
					alert('Something seems to be wrong with the Tab bar structure. No copy possible');
				}
				return;
			}
			else
			{
				for( var i = 0; i < panels.length; i++ )
				{
					tabRefs[i].setAttribute("href", "#" + panels[i].id.toString());
				}
			}
		}
		
		// Construct the assets list using the array of assets returned by the static getAssets() function
		var assets = JQuery.DesignTime.Widget.Tabs.getAssets();
		for (var i=0; i<assets.length; i++)
		{
			assetInfo = new AssetInfo(assets[i].fullPath, assets[i].file, assets[i].type, true, false);
			assetList.push(assetInfo);
		}
		
		if (assetList && assetList.length)
		{
			targetDom.copyAssets(assetList);
		}
		
		targetDom.addJavaScript(newConJs, false);
		targetDom.setSelectedNode(newTab);
	};
}

JQuery.DesignTime.Widget.Tabs.prototype.initHeightStyleArray = function()
{
	this.heightStyleArray.push("auto");
	this.heightStyleArray.push("fill");
	this.heightStyleArray.push("content");
}

JQuery.DesignTime.Widget.Tabs.prototype.getHeightStyleOptions = function ()
{
	return this.heightStyleArray;
}

//--------------------------------------------------------------------
// FUNCTION:
//  	getDisabledValue
//
// DESCRIPTION:
//  	This method returns the value of the disabled attribute in the widget constructor.
//		If user changes the disabled value in the code. This is where we 'read' that updated 
//		value from the object
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	Boolean: The value of the disabled attribute as boolean
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getDisabledValue = function()
{	
	if( this.opts && this.opts.disabled != null && typeof this.opts.disabled != 'undefined' )
	{
		return (this.opts.disabled == true);
	}
	return false;
}

//--------------------------------------------------------------------
// FUNCTION:
//  	setDisabledValue
//
// DESCRIPTION:
//  	When a new value for disabled is attained for the disabled attribute from the PI
//		we have to update our opts object with this new disabled value and initiate an update cycle
//		for this change to be reflected in code.
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	None
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.setDisabledValue = function(disabledValue)
{	
	if( disabledValue == null || typeof disabledValue == "undefined" )
		return;

	if (!this.opts)
		this.opts = {};
		
	var oldDisabledValue = this.opts.disabled	;
	if( disabledValue == true )
	{
		this.opts.disabled = true;
	}	
	else
	{
		this.opts.disabled = null;
	}
	
	if( oldDisabledValue != this.opts.disabled )
	{
		this.updateOptions(this.widgetType, this.opts);
	}
}

//--------------------------------------------------------------------
// FUNCTION:
//  	getHeightStyleIndex
//
// DESCRIPTION:
//  	This method will return the index of the heightStyle List element
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	Number: The value of the index of dateformat list
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getHeightStyleIndex = function()
{
	if( this.opts && this.opts.heightStyle != null && typeof this.opts.heightStyle != 'undefined' )
	{
		var heightStyleArray = this.getHeightStyleOptions();
		for( var i = 0; i < heightStyleArray.length; i++ )
		{
			if( this.opts.heightStyle.toString() == heightStyleArray[i] )
				return i;
		}
	}
	return 0;
}

//--------------------------------------------------------------------
// FUNCTION:
//  	setHeightStyleIndex
//
// DESCRIPTION:
//  	Here we set the opts object from the new index set in the heightStyle
//		list.
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	None
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.setHeightStyleIndex = function(heightStyleIndex)
{
	if( heightStyleIndex == null || typeof heightStyleIndex == "undefined" )
		return;
		
	if (!this.opts)
		this.opts = {};
	
	var oldDateValue = this.opts.heightStyle;
	
	if( heightStyleIndex == 0 )
		this.opts.heightStyle = null;
	else
		this.opts.heightStyle = this.getHeightStyleOptions()[heightStyleIndex];
	
	if( oldDateValue != this.opts.heightStyle )
		this.updateOptions(this.widgetType, this.opts);	
}

//--------------------------------------------------------------------
// FUNCTION:
//  	initAnimationArray
//
// DESCRIPTION:
//  	Initializes the position array with predefined values.
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	None
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.initAnimationArray = function()
{
	this.animationArray.push("none");
	this.animationArray.push("blind");
	this.animationArray.push("bounce");
	this.animationArray.push("clip");
	this.animationArray.push("drop");
	this.animationArray.push("fade");
	this.animationArray.push("fold");
	this.animationArray.push("highlight");
	this.animationArray.push("puff");
	this.animationArray.push("pulsate");
	this.animationArray.push("scale");
	this.animationArray.push("shake");
	this.animationArray.push("slide");
	
}

//--------------------------------------------------------------------
// FUNCTION:
//  	getAnimationArray
//
// DESCRIPTION:
//  	Return the position Array containing all possible values for 'position'
//		attribute of the constructor object
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	N/A
//--------------------------------------------------------------------


JQuery.DesignTime.Widget.Tabs.prototype.getAnimationArray = function()
{
	return this.animationArray;
}

JQuery.DesignTime.Widget.Tabs.prototype.getHideEffectIndex = function()
{
	if( this.opts && this.opts.hide != null && typeof this.opts.hide != 'undefined' )
	{
		if( this.opts.hide.effect && typeof this.opts.hide.effect != 'undefined')
		{
			for( var i = 0; i < this.animationArray.length; i++ )
			{
				if( this.opts.hide.effect.toString() == this.animationArray[i] )
					return i;
			}
		}
	}
	return 0;
}
JQuery.DesignTime.Widget.Tabs.prototype.setHideEffectIndex = function(listIndex)
{
	if( listIndex == null || typeof listIndex == "undefined" )
		return;
			
	if (!this.opts)
		this.opts = {};
		
	if (!this.opts.hide)
		this.opts.hide = {};
		
	var oldEffectValue = this.opts.hide.effect;	
	
	if( listIndex == 0 )
		this.opts.hide.effect = null;
	else
		this.opts.hide.effect = this.animationArray[listIndex];	
		
	if( this.opts.hide && !this.opts.hide.effect )	
	{
		this.opts.hide = null;
		this.updateOptions(this.widgetType, this.opts);	
	}
	else if( oldEffectValue != this.opts.hide.effect )	
		this.updateOptions(this.widgetType, this.opts);	
}
JQuery.DesignTime.Widget.Tabs.prototype.getHideDurationValue = function()
{
	if( this.opts && this.opts.hide != null && typeof this.opts.hide != 'undefined' )
	{
		if( this.opts.hide.duration && typeof this.opts.hide.duration != 'undefined')
		{
			return this.opts.hide.duration;
		}
	}
	return "400";
}

JQuery.DesignTime.Widget.Tabs.prototype.setHideDurationValue = function(hideValue)
{
	if (hideValue == null || typeof hideValue == "undefined")
		return;
			
	if (!this.opts)
		this.opts = {};
		
	if (!this.opts.hide)
		this.opts.hide = {};
		
	var oldDurationValue = this.opts.hide.duration;	
	
	if( hideValue == "400" || parseInt(hideValue).toString() == 'NaN')
		this.opts.hide.duration = null;
	else
		this.opts.hide.duration = parseInt(hideValue);	
		
	if( this.opts.hide && !this.opts.hide.effect && !this.opts.hide.duration )	
	{
		this.opts.hide = null;
		this.updateOptions(this.widgetType, this.opts);	
	}
	else if( oldDurationValue != this.opts.hide.duration )	
		this.updateOptions(this.widgetType, this.opts);	
}

JQuery.DesignTime.Widget.Tabs.prototype.getShowEffectIndex = function()
{
	if( this.opts && this.opts.show != null && typeof this.opts.show != 'undefined' )
	{
		if( this.opts.show.effect && typeof this.opts.show.effect != 'undefined')
		{
			for( var i = 0; i < this.animationArray.length; i++ )
			{
				if( this.opts.show.effect.toString() == this.animationArray[i] )
					return i;
			}
		}
	}
	return 0;
}
JQuery.DesignTime.Widget.Tabs.prototype.setShowEffectIndex = function(listIndex)
{
	if( listIndex == null || typeof listIndex == "undefined" )
		return;
			
	if (!this.opts)
		this.opts = {};
		
	if (!this.opts.show)
		this.opts.show = {};
		
	var oldEffectValue = this.opts.show.effect;	
	
	if( listIndex == 0 )
		this.opts.show.effect = null;
	else
		this.opts.show.effect = this.animationArray[listIndex];	
		
	if( this.opts.show && !this.opts.show.effect )	
	{
		this.opts.show = null;
		this.updateOptions(this.widgetType, this.opts);	
	}
	else if( oldEffectValue != this.opts.show.effect )	
		this.updateOptions(this.widgetType, this.opts);	
}

JQuery.DesignTime.Widget.Tabs.prototype.getShowDurationValue = function()
{
	if( this.opts && this.opts.show != null && typeof this.opts.show != 'undefined' )
	{
		if( this.opts.show.duration && typeof this.opts.show.duration != 'undefined')
		{
			return this.opts.show.duration;
		}
	}
	return "400";
}
JQuery.DesignTime.Widget.Tabs.prototype.setShowDurationValue = function(showValue)
{
	if (showValue == null || typeof showValue == "undefined")
		return;
			
	if (!this.opts)
		this.opts = {};
		
	if (!this.opts.show)
		this.opts.show = {};
		
	var oldDurationValue = this.opts.show.duration;	
	
	if( showValue == "400" || parseInt(showValue).toString() == 'NaN')
		this.opts.show.duration = null;
	else
		this.opts.show.duration = parseInt(showValue);	
		
	if( this.opts.show && !this.opts.show.effect && !this.opts.show.duration )	
	{
		this.opts.show = null;
		this.updateOptions(this.widgetType, this.opts);	
	}
	else if( oldDurationValue != this.opts.show.duration )	
		this.updateOptions(this.widgetType, this.opts);	
}

//--------------------------------------------------------------------
// FUNCTION:
//  	initOrientationArray
//
// DESCRIPTION:
//  	Initializes the orientation array with predefined values.
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	None
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.initOrientationArray = function()
{
	this.orientationArray.push("horizontal");
	this.orientationArray.push("vertical");	
}

//--------------------------------------------------------------------
// FUNCTION:
//  	getOrientationOptions
//
// DESCRIPTION:
//  	Return the orientation Array containing all possible values for 'orientation'
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	N/A
//--------------------------------------------------------------------


JQuery.DesignTime.Widget.Tabs.prototype.getOrientationOptions = function()
{
	return this.orientationArray;
}

JQuery.DesignTime.Widget.Tabs.prototype.getOrientationInfo = function()
{
	if (!this.dom)
		return;
		
	var orientationInfo = [];
	var consRegExp = this.getConstructorRegExp();
	var scriptTags = this.dom.getElementsByTagName("script");
	for( var i = 0; i < scriptTags.length; i++ )
	{
		var sTag = scriptTags[i];
		var src = sTag.innerHTML;
		if(!src)
			continue;
			
		var matchStrings = src.match(consRegExp);
		if( matchStrings && matchStrings.length )
		{
			var widgetStr = matchStrings[0];
			var parseString = "";
			var parseArray = widgetStr.split(this.widgetType);
			if (parseArray.length > 1)
			{
				for( var i = 1; i < parseArray.length; i++ )
				{
					parseString += parseArray[i];
				}
				
				if (parseString)
				{
					parseArray = JQuery.DesignTime.Editing.Utils.getContainedString(parseString, '(', ')', true);
					
					if (!parseArray || parseArray.length != 3)
						return;
					
					var constructorIndex = widgetStr.indexOf(parseArray[0]);
					orientationInfo.push(widgetStr.slice(0, constructorIndex) + parseArray[0]);
					orientationInfo.push(sTag);
					return orientationInfo;
				}
			}
		}
	}	
	return null;
}

//--------------------------------------------------------------------
// FUNCTION:
//  	getOrientationIndex
//
// DESCRIPTION:
//  	This method will return the index of orientation Array 
//		corresponding the current orientation of the tabs widget
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	Number: The value of the index of position list
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.getOrientationIndex = function()
{
	var orientationInfo = this.getOrientationInfo();
	
	//The returned array should contain 2 entries corresponding to the widget string and its HTML node
	if (!orientationInfo || orientationInfo.length != 2)
		return 0;
	
	var originalNode = orientationInfo[1];
	
	if (!originalNode)
		return 0;
	
	var originalHtml = originalNode.innerHTML;
	var widgetString = orientationInfo[0];
	var index = originalHtml.indexOf(widgetString)
	var postWidgetString = originalHtml.slice(index + widgetString.length);
	
	if (postWidgetString.match(/\.addClass\( "ui-tabs-vertical ui-helper-clearfix" \)/g))
	{
		return 1;
	}
	
	return 0;
}

//--------------------------------------------------------------------
// FUNCTION:
//  	setPositionIndex
//
// DESCRIPTION:
//  	Changes the orientation of the tabs widget to the value at the index provided
//
// ARGUMENTS:
//  	None
//
// RETURNS:
//  	None
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Tabs.prototype.setOrientationIndex = function(positionIndex)
{
	//Get orientation info and decipher whether we are already vertical. This is very similar to getOrientationIndex()
	var orientationInfo = this.getOrientationInfo();
	
	//The returned array should contain 2 entries corresponding to the widget string and its HTML node
	if (!orientationInfo || orientationInfo.length != 2)
		return;
	
	var originalNode = orientationInfo[1];
	
	if (!originalNode)
		return;
	
	var originalHtml = originalNode.innerHTML;
	var widgetString = orientationInfo[0];
	var index = originalHtml.indexOf(widgetString)
	var preWidgetString = originalHtml.slice(0, index);
	var postWidgetString = originalHtml.slice(index + widgetString.length);
	var verticalOrientation = false;
	
	if (postWidgetString.match(/\.addClass\( "ui-tabs-vertical ui-helper-clearfix" \)/g))
	{
		verticalOrientation = true;
	}
	
	if (verticalOrientation)
	{
		// We are already in vertical state
		if (positionIndex)
			return;
			
		//postWidgetString = postWidgetString.replace (/\.addClass\( "ui-tabs-vertical\s*ui-helper-clearfix" \)\s*;\s*/g, "");	
		postWidgetString = postWidgetString.replace (/\.addClass\( "ui-tabs-vertical\s*ui-helper-clearfix" \)\s*;\s*\$.*?\( "ui-corner-left" \)/g, "");	
		originalNode.innerHTML = preWidgetString + widgetString + postWidgetString;			
	}
	else
	{
		//Already horizontal
		if (!positionIndex)
			return;
			
		originalNode.innerHTML = preWidgetString + widgetString + ".addClass( \"ui-tabs-vertical ui-helper-clearfix\" );\n\
	$( \"#Tabs1 li\" ).removeClass( \"ui-corner-top\" ).addClass( \"ui-corner-left\" )" + postWidgetString;	
		var styleNodes = this.dom.getElementsByTagName('style');
		var isVerticalStyleAdded = false;	
		var styleNodes = this.dom.getElementsByTagName('style');
			
		if (styleNodes && styleNodes != undefined)
		{
			for (var i = styleNodes.length-1; i >= 0; i--)
			{
				if (styleNodes[i] && styleNodes[i].innerHTML && styleNodes[i].innerHTML.match("ui-tabs-vertical"))
				{
					isVerticalStyleAdded = true;
					break;
				}
			}
		}	
		
		if (!isVerticalStyleAdded)
		{
			var headNodes = this.dom.getElementsByTagName('head');
			
			if (headNodes && headNodes[0])
				var headNode = headNodes[0];
				
			if (!headNode || headNode == undefined)
				return;
			
			headNode.innerHTML = headNode.innerHTML + "<style>\n\
	.ui-tabs-vertical { width: 55em; }\n\
	.ui-tabs-vertical .ui-tabs-nav { padding: .2em .1em .2em .2em; float: left; width: 12em; }\n\
	.ui-tabs-vertical .ui-tabs-nav li { clear: left; width: 100%; border-bottom-width: 1px !important; border-right-width: 0 !important; margin: 0 -1px .2em 0; }\n\
	.ui-tabs-vertical .ui-tabs-nav li a { display:block; }\n\
	.ui-tabs-vertical .ui-tabs-nav li.ui-tabs-active { padding-bottom: 0; padding-right: .1em; border-right-width: 1px; border-right-width: 1px; }\n\
	.ui-tabs-vertical .ui-tabs-panel { padding: 1em; float: right; width: 40em;}\n\
</style>";
		}
	}
}

JQuery.DesignTime.Widget.Tabs.getDeleteWidgetCallback = function(removeString, widgetId)
{
	var deleteFunction = function(e)
	{
		var targetDom = e.target.ownerDocument;					
		var scriptTags = targetDom.getElementsByTagName("script");
		for( var i = 0; i < scriptTags.length; i++ )
		{
			var str = scriptTags[i].innerHTML;
			var index = str.indexOf(removeString);
			if( index >= 0 )
			{
				var strBefore = str.substr(0, index);
				var strAfter = str.substr(index+removeString.length);
				while( strBefore.length > 0 && ( strBefore.charAt(strBefore.length-1) == ' ' ||
												strBefore.charAt(strBefore.length-1) == '\t' ||
												strBefore.charAt(strBefore.length-1) == '\n' ||
												strBefore.charAt(strBefore.length-1) == '\r' ) )
				{
					strBefore = strBefore.substr(0, strBefore.length-1);
				}
				// We'll store the new InnerHTML to newInnerHTML and we'll decide later whether we'll replace the inner value with this
				// one or we'll simply remove the SCRIPT tag.
				var newInnerHTML = strBefore + strAfter;

				// Look if there is any valid JS code remining in the SCRIPT tag; of empty (or only comments were found) => go and remove it
				var tempInnerHTML = newInnerHTML;
				if (tempInnerHTML && tempInnerHTML.replace)
				{
					tempInnerHTML = tempInnerHTML.replace(/[\r\n]*(?:\<\!\-\-|\/\/\-\-\>)[\r\n]*/gi, "");
					tempInnerHTML = tempInnerHTML.replace(/[\r\n\s\t]*/gi, "")
				}

				// If the InnerHTML is empty, we'll remove the entire SCRIPT tag.
				if (tempInnerHTML === "")
				{
					scriptTags[i].outerHTML = "";
				}
				else
				{
					scriptTags[i].innerHTML = newInnerHTML;
				}
				
				// Get WidgetManager instance
				var widgetMgr = JQuery.DesignTime.Widget.Manager.getManagerForDocument(targetDom);
				
				if (!widgetMgr)
					return;
			
				// Search for widgets of the same type in the page, but different from the current one (compared by ID)
				var count = 0;
				var allWidgets = widgetMgr.getAllWidgets('tabs');
				for (var widget in allWidgets) {
					if (widget != widgetId)
					{
						count++;
						break;
					}
				}
				
				if (count == 0)
				{
					//Remove the style tag for vertical orientation if it was added
					var styleNodes = targetDom.getElementsByTagName('style');
			
					if (styleNodes && styleNodes != undefined)
					{
						for (var i = styleNodes.length-1; i >= 0; i--)
						{
							if (styleNodes[i].innerHTML.match("ui-tabs-vertical"))
							{
								styleNodes[i].outerHTML = "";
								break;
							}
						}
					}
					
					// There are no more widgets remaining in the page of the current type, we'll remove the assets as well
					if (!JQuery.DesignTime.Widget.Tabs)
					  return;
					  
					var assets = JQuery.DesignTime.Widget.Tabs.getAssets();
					var tags = new Array();
					tags = tags.concat(targetDom.getElementsByTagName("script"));
					tags = tags.concat(targetDom.getElementsByTagName("link"));
					
					for (var j=0; j<tags.length; j++)
					{
					
						var tag = tags[j];
						if (tag && tag.getAttribute)
						{
							// Get the value to search; the attribute is different according to tag name: script or link
							var valueToSearch = tag.getAttribute("src");
							if (!valueToSearch)
							{
								valueToSearch = tag.getAttribute("href");
							}

							// Once we have a value, we test it against all assets
							if( valueToSearch && valueToSearch.match(/ui/) )
							{
								//Adding a special case for jquery.ui.theme.css and jquery.ui.core.css which should not be removed on removal of a widget as these files are commonly shared amongst widgets
								if (!valueToSearch.match(/jquery\.ui\.theme\.min\.css/) && !valueToSearch.match(/jquery\.ui\.core\.min\.css/))
								{	
									for (var k=0; k<assets.length; k++)
									{
										if (assets[k].type)
										{
											// If the current tag's value matches an asset we'll remove the tag from page
											if (valueToSearch.match && valueToSearch.match(new RegExp("(?:^|[\\/\\\\])" + dwscripts.escRegExpChars(assets[k].file) + "$", "gi")))
											{
												tag.outerHTML = "";
												break;
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	};
	return deleteFunction;
}
