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

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

//Global variables----------------------------------------------------
  var buttonIdString = dw.loadString("jquery/widgets/Buttonset/newSnippet/id");
  var radioIdString = dw.loadString("jquery/widgets/Radio/newSnippet/id");
  var checkboxIdString = dw.loadString("jquery/widgets/Checkbox/newSnippet/id");
  var notInDomIdArray = [];
//--------------------------------------------------------------------

//--------------------------------------------------------------------
// FUNCTION:
//   Buttonset
//
// DESCRIPTION:
//	 This is the constructor method for this design time buttonset object.
//	 It calls the base widget constructor which helps us inherit all base methods
//	 
//   It also manages the Buttonset's widget markup in the design view. This constructor
//   is registered in the JQuery Widget translator found at:
//
//       Configuration/Translators/jQueryWidget.htm
//	 
//
// 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.Buttonset = function(dom, element, consArgs)
{
	JQuery.DesignTime.Widget.Base.call(this, dom, element);
	
	this.init(element);
	this.type = this.getButtonsetType();
};

// JQuery.DesignTime.Widget.Buttonset 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.Buttonset.prototype = new JQuery.DesignTime.Widget.Base();

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

//--------------------------------------------------------------------
// FUNCTION:
//   init
//
// DESCRIPTION:
//   Initializes the design-time object's properties. This  method is
//   called from the constructor and refresh() methods.
//
// ARGUMENTS:
//   element - object - The widget's top-level DOM element.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.prototype.init = function(element)
{
  this.element = this.getElement(element);
  this.canRefresh = true;
};
JQuery.DesignTime.Widget.Buttonset.prototype.getButtonsetType = function(element)
{
	var unknownType = "unknown"
	var buttonType = unknownType;
	var buttonChildren = this.getElementChildren(this.element);
	
	if (!buttonChildren)
		return "";
		
	if (buttonChildren.length == 0)
		return "button";
		
	var firstButton = buttonChildren[0];	
	
	if (firstButton.tagName == "BUTTON")
	{
		for (var i = 1; i < buttonChildren.length; i++)
		{
			if (buttonChildren[i].tagName != "BUTTON")
				return unknownType;
		}
		buttonType = "button";
	}
	else if (firstButton.tagName == "INPUT" && firstButton.getAttribute && 
			(firstButton.getAttribute("type") == "radio" || firstButton.getAttribute("type") == "checkbox"))
	{
		buttonType = firstButton.getAttribute("type");
		for (var i = 1; i < buttonChildren.length; i++)
		{
			//Even indices. Should be valid input tags like the first tag
			if (!(i%2))					
			{
				if (buttonChildren[i].tagName != "INPUT" || buttonChildren[i].getAttribute("type") != buttonType)
					return unknownType;
			}
			else
			{
				//This should be checked to be a valid label tag in correspondence with its input tag
				inputNode = buttonChildren[i-1];
				labelNode = buttonChildren[i];
				
				if (!inputNode || !labelNode || labelNode.tagName != "LABEL" || 
				   (!inputNode.getAttribute || !labelNode.getAttribute || inputNode.getAttribute("id") != labelNode.getAttribute("for")))
					return unknownType;
			}
		}
	}
	
	return buttonType;	
}

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

JQuery.DesignTime.Widget.Buttonset.getAssets = function()
{
	var assets = new Array();
	
	assetObject = new Object();
	assetObject.fullPath = jQButtonImagesPath;
	assetObject.file = jQButtonImagesFile;
	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 = jQButtonCssWidgetPath;
	assetObject.file = jQButtonCssWidgetFile;
	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 = jQButtonJsPath;
	assetObject.file = jQButtonJsFile;
	assetObject.type = "javascript";
	assets.push(assetObject);
	
	return (assets);
	
};

//--------------------------------------------------------------------
// FUNCTION:
//   refresh
//
// DESCRIPTION:
//   None
//
// ARGUMENTS:
//   This is dummy method, doesn't do anything now. But can be used 
//	 for taking some action whenever something changes in the widget
//
//   This method gets called from the translator if a design-time
//   object already exists for a specific widget ID
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.prototype.refresh = function()
{
  if (!this.canRefresh)
	return;  
};

//--------------------------------------------------------------------
// FUNCTION:
//   getLabelElements
//
// DESCRIPTION:
//   This method with return the list of all label node elements (Not the ids)
//	This will be different for different kinds of buttonsets
//
// ARGUMENTS:
//
// RETURNS:
//   Array of all Label Elements (or Section headings)
//--------------------------------------------------------------------
JQuery.DesignTime.Widget.Buttonset.prototype.getLabels = function()
{
	var labels = this.getButtonsetLabels();
	
	if (!labels || labels.length == 0)
		return null;	
	else
		return labels;
}

JQuery.DesignTime.Widget.Buttonset.prototype.getButtonsetLabels = function()
{
	this.ensureValidElements();
	var labels = new Array();
	var buttonsetChildren = this.getElementChildren(this.element);
	for (var i = 0; i < buttonsetChildren.length; i++)
	{
		var labelElement = null;
		if (this.type == "button")
		{
			labelElement = buttonsetChildren[i];
		}
		else if (this.type == "radio" || this.type == "checkbox")
		{
			if (i%2)
				labelElement = buttonsetChildren[i];
			else
				continue;
		}
		
		var label = "";
		if (labelElement)
		{
			label = dwscripts.collectTextInNode(labelElement);
			label = dwscripts.entityNameDecode(label); 
			label = dwscripts.trim(label);
			
			if (label.length == 0)
				label = dw.loadString("jquery/widget/unlabeled button");
		}
		else
		{
			label = dw.loadString("jquery/widget/broken buttonset");
		}
		
		labels.push(label);
	}
	
	return labels;
}

//--------------------------------------------------------------------
// FUNCTION:
//   addNewButton
//
// DESCRIPTION:
//   Adds a new button after the open (current) button.
//
// ARGUMENTS:
//  
// RETURNS:
//   Returns the DOM element object that represents the new button
//   or undefined if a new button was not added.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.prototype.addNewButton = function(selIndex)
{
	var counter = 1;
  
	var labels = this.getLabels();
	var numLabels = 0;
	
	if (labels)
	{
		numLabels = labels.length;
		counter = numLabels + 1;
	}
	
	if (selIndex >= numLabels)
		return;
  
	if (this.type == "button")
	{
		var btnId = JQuery.DesignTime.Widget.Buttonset.getNewButtonId(buttonIdString);	
		var buttonSnippet = JQuery.DesignTime.Widget.Buttonset.getNewButtonSnippet(counter, btnId);
		var selButton = this.getButtonElement(selIndex);
	}
	else if (this.type == "radio")
	{
		var radiosetId = this.element_id;
		var btnId = JQuery.DesignTime.Widget.Buttonset.getNewButtonId(radioIdString);	
		var buttonSnippet = JQuery.DesignTime.Widget.Buttonset.getNewRadioButtonSnippet(counter, btnId, radiosetId);
		var selButton = this.getLabelElement(selIndex);
	}
	else if (this.type == "checkbox")
	{
		var btnId = JQuery.DesignTime.Widget.Buttonset.getNewButtonId(checkboxIdString);	
		var buttonSnippet = JQuery.DesignTime.Widget.Buttonset.getNewCheckboxButtonSnippet(counter, btnId);
		var selButton = this.getLabelElement(selIndex);
	}
  
	if (selButton && selButton.ownerDocument )
	{
		// Add it after the current button.
		selButton.outerHTML = selButton.outerHTML + buttonSnippet;
	}
	else if ( this.element && this.element.ownerDocument )
	{
		// Add it at the top.
		this.element.innerHTML = buttonSnippet + this.element.innerHTML;
	}
};

//--------------------------------------------------------------------
// FUNCTION:
//   JQuery.DesignTime.Widget.Buttonset.getNewButtonSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string containing the
//   markup for a new Buttonset Button.
//
// ARGUMENTS:
//  counter - integer - Unique integer value appended to the Button label 
//                      so that it is unique.
//
// RETURNS:
//   String that is the HTML markup fragment for the button.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.getNewButtonSnippet = function(counter, id)
{
  if ( typeof counter == 'undefined' ) counter = "";
  
  tab = dw.loadString('jquery/widgets/Buttonset/newSnippet/label'); 
	
  return '<button id="' + id + '">' + tab + counter + '</button>';
};

JQuery.DesignTime.Widget.Buttonset.prototype.getButtonElement = function(index)
{
	this.ensureValidElements();
	var buttonsetChildren = this.getElementChildren(this.element);
	
	if (this.type == "button")
	{
		if (index <0 || index >= buttonsetChildren.length)
			return null;
		
		return buttonsetChildren[index];
	}
	else if (this.type == "radio" || this.type == "checkbox")
	{
		if (index <0 || index >= (buttonsetChildren.length/2))
			return null;
			
		return buttonsetChildren[index*2];	
	}
	return null;
}

JQuery.DesignTime.Widget.Buttonset.prototype.getLabelElement = function(index)
{
	
	if (this.type == "button")
	{
		return this.getButtonElement(index)
	}
	else if (this.type == "radio" || this.type == "checkbox")
	{
		this.ensureValidElements();
		var buttonsetChildren = this.getElementChildren(this.element);
	
		if (index <0 || index >= (buttonsetChildren.length/2))
			return null;
			
		return buttonsetChildren[index*2 + 1];	
	}
	return null;
}

JQuery.DesignTime.Widget.Buttonset.prototype.deleteButton = function(selIndex)
{
	var selButton = this.getButtonElement(selIndex);
	
	if (!selButton)
		return;
	
	if (this.type == "button")
	{
		selButton.outerHTML = "";
	}
	else if (this.type == "radio" || this.type == "checkbox")
	{
		var selLabel = selButton.nextSibling;
		
		if (!selLabel)
			return;
		
		selButton.outerHTML = "";
		selLabel.outerHTML = "";
	}
		
}
JQuery.DesignTime.Widget.Buttonset.prototype.moveButtonUp = function(selIndex)
{
	if (selIndex <= 0)
		return;
		
	var selButton = this.getButtonElement(selIndex);
	var prevButton = this.getButtonElement(selIndex-1);
	
	if (!selButton || !prevButton)
		return;
	
	if (this.type == "button")
	{
		prevButton.outerHTML = selButton.outerHTML + prevButton.outerHTML;
		selButton.outerHTML = "";
	}
	else if (this.type == "radio" || this.type == "checkbox")
	{
		var selLabel = selButton.nextSibling;
		var prevLabel = prevButton.nextSibling;
		
		if (!selLabel || !prevLabel)
			return;
		
		prevButton.outerHTML = selButton.outerHTML + selLabel.outerHTML + prevButton.outerHTML + prevLabel.outerHTML;
		selButton.outerHTML = "";
		selLabel.outerHTML = "";
		prevLabel.outerHTML = "";
	}
}
JQuery.DesignTime.Widget.Buttonset.prototype.moveButtonDown = function(selIndex)
{
	var labels = this.getLabels();
	if (!labels || selIndex >= labels.length-1)
		return;
		
	var selButton = this.getButtonElement(selIndex);
	var nextButton = this.getButtonElement(selIndex+1);
	
	if (!selButton || !nextButton)
		return;
	
	if (this.type == "button")
	{
		nextButton.outerHTML = nextButton.outerHTML + selButton.outerHTML;
		selButton.outerHTML = "";
	}
	else if (this.type == "radio" || this.type == "checkbox")
	{
		var selLabel = selButton.nextSibling;
		var nextLabel = nextButton.nextSibling;
		
		if (!selLabel || !nextLabel)
			return;
		
		nextButton.outerHTML = nextButton.outerHTML + nextLabel.outerHTML + selButton.outerHTML + selLabel.outerHTML;
		selButton.outerHTML = "";
		selLabel.outerHTML = "";
		nextLabel.outerHTML = "";
	}
}

//--------------------------------------------------------------------
// FUNCTION:
//   JQuery.DesignTime.Widget.Buttonset.getNewButtonsetConstructorSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string that contains the
//   constructor snippet for creating a JQuery widget with the specified id.
//	 We use the same method for radio and checkbox sets
//
// 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.Buttonset.getNewButtonsetConstructorSnippet = function(id)
{
  return ' $(function() {\n\t$( "#' + id + '" ).buttonset(); \n});';
};

//--------------------------------------------------------------------
// FUNCTION:
//   JQuery.DesignTime.Widget.Buttonset.getNewButtonsetSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string containing the
//   markup for a complete Buttonset.
//
// ARGUMENTS:
//  id - string - The string to use as the widget's id attribute.
//
// RETURNS:
//   String that is the HTML markup fragment for the panel.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.getNewButtonsetSnippet = function(id)
{
	var numButtons = 3;
	var buttonsetSnippet = '<div id="' + id + '">'
	notInDomIdArray = [];
  
	for (var i = 0; i < numButtons; i++)
		notInDomIdArray[i] = JQuery.DesignTime.Widget.Buttonset.getNewButtonId(buttonIdString);
  
	for ( var i = 0 ; i < numButtons ; i++ ) {
		buttonsetSnippet += JQuery.DesignTime.Widget.Buttonset.getNewButtonSnippet(i+1, notInDomIdArray[i]) ;
	}
	buttonsetSnippet += '</div>';
  
	notInDomIdArray = [];
	return buttonsetSnippet;
};


//--------------------------------------------------------------------
// FUNCTION:
//   JQuery.DesignTime.Widget.Buttonset.getNewRadioSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string containing the
//   markup for a complete Buttonset of type radio.
//
// ARGUMENTS:
//  id - string - The string to use as the widget's id attribute.
//
// RETURNS:
//   String that is the HTML markup fragment for the widget.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.getNewRadioSnippet = function(id)
{
	var numButtons = 3;
	var radioSnippet = '<div id="' + id + '">'
	notInDomIdArray = [];
  
	for (var i = 0; i < numButtons; i++)
		notInDomIdArray[i] = JQuery.DesignTime.Widget.Buttonset.getNewButtonId(radioIdString);
  
	for ( var i = 0 ; i < numButtons ; i++ ) {
		radioSnippet += JQuery.DesignTime.Widget.Buttonset.getNewRadioButtonSnippet(i+1, notInDomIdArray[i], id) ;
	}
	radioSnippet += '</div>';
  
	notInDomIdArray = [];
	return radioSnippet;
};

//--------------------------------------------------------------------
// FUNCTION:
//   JQuery.DesignTime.Widget.Buttonset.getNewCheckboxSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string containing the
//   markup for a complete Buttonset of type radio.
//
// ARGUMENTS:
//  id - string - The string to use as the widget's id attribute.
//
// RETURNS:
//   String that is the HTML markup fragment for the widget.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.getNewCheckboxSnippet = function(id)
{
	var numButtons = 3;
	var checkboxSnippet = '<div id="' + id + '">'
	notInDomIdArray = [];
  
	for (var i = 0; i < numButtons; i++)
		notInDomIdArray[i] = JQuery.DesignTime.Widget.Buttonset.getNewButtonId(checkboxIdString);
  
	for ( var i = 0 ; i < numButtons ; i++ ) {
		checkboxSnippet += JQuery.DesignTime.Widget.Buttonset.getNewCheckboxButtonSnippet(i+1, notInDomIdArray[i]) ;
	}
	checkboxSnippet += '</div>';
  
	notInDomIdArray = [];
	return checkboxSnippet;
};

//--------------------------------------------------------------------
// FUNCTION:
//   JQuery.DesignTime.Widget.Buttonset.getNewRadioButtonSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string containing the
//   markup for a new radio Button.
//
// ARGUMENTS:
//  counter - integer - Unique integer value appended to the Button label 
//                      so that it is unique.
//
// RETURNS:
//   String that is the HTML markup fragment for the button.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.getNewRadioButtonSnippet = function(counter, id, radiosetId)
{
  if ( typeof counter == 'undefined' ) counter = "";
  if ( typeof radiosetId == 'undefined' ) radiosetId = "radio";
  
  tab = dw.loadString('jquery/widgets/Buttonset/newSnippet/label'); 
	tab += " ";
	
	return '<input type="radio" name="' + radiosetId + '" id="' + id + '"><label for="' + id + '">' + tab + counter + '</label>';
};

//--------------------------------------------------------------------
// FUNCTION:
//   JQuery.DesignTime.Widget.Buttonset.getNewCheckboxButtonSnippet
//
// DESCRIPTION:
//   Static utility function that returns a string containing the
//   markup for a new checkbox Button.
//
// ARGUMENTS:
//  counter - integer - Unique integer value appended to the Button label 
//                      so that it is unique.
//
// RETURNS:
//   String that is the HTML markup fragment for the button.
//--------------------------------------------------------------------

JQuery.DesignTime.Widget.Buttonset.getNewCheckboxButtonSnippet = function(counter, id)
{
  if ( typeof counter == 'undefined' ) counter = "";
  
  tab = dw.loadString('jquery/widgets/Buttonset/newSnippet/label'); 
	tab += " ";

	return '<input type="checkbox" id="' + id + '"><label for="' + id + '">' + tab + counter + '</label>';
};

JQuery.DesignTime.Widget.Buttonset.getNewButtonId = function (idString)
{
	var dom = dw.getDocumentDOM();
	
	if (!dom)
		return;
		  
	if (!idString)
	{
			idString = buttonIdString;
	}
	
	var idElems = dom.body.getElementsByAttributeName("id");
	var suffix = 1;
	var newName = idString + 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 = idString + suffix;
	}


  return newName; 
  
}