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

var helpDoc = MM.HELP_jQueryAutocomplete;

var AUTOCOMPLETE_ID;
var	SOURCE_INPUT;
var	MINLENGTH_INPUT;
var	DELAY_INPUT;
var	APPEND_INPUT;
var AUTOFOCUS_CHECK;
var MY_LIST;
var AT_LIST;
var COLLISION_LIST;


// ********************* API FUNCTIONS ***************************

//--------------------------------------------------------------------
// FUNCTION:
//   canInspectSelection
//
// DESCRIPTION:
//   This is a Property Inspector API function that gets called
//   whenever the selection in the document changes to decide whether
//   or not this property inspector should be displayed.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   true if the currently selected node is a Autocomplete element,
//   false if it is not.
//--------------------------------------------------------------------

function canInspectSelection() 
{
  var bCanInspectSelection = false;
  var dom = dw.getDocumentDOM();
  var selectedNode = dom.getSelectedNode();
	
  if ( !selectedNode || !selectedNode.getTranslatedAttribute )
    return false;

  var attr = selectedNode.getTranslatedAttribute('autocomplete');
  if ( attr && attr.length > 0 )
  {
    bCanInspectSelection = true;
    
    // If the widget manager is out of sync, run the translator
    var widgetMgr = JQuery.DesignTime.Widget.Manager.getManagerForDocument(dom); 
	
    if ( !widgetMgr.getWidget('autocomplete', selectedNode.id ) )
    { 
			//This means that we did find a translated attribute in the widget html, but we 
			// do not find it in our widget manager. Now earlier we used to explicitly run 
			// the translator again at this step hoping that we will be able to identify widget 
			//this time, in case the translator misbehaved in its last run. 
			// This was causing chaos in form elements with the 'autocomplete' attribute set to true
			// where the PI refreshed infinitely.
			//
			// So now we don't call the translator again and consider the widget manager the authority 
			// on deciding if this is a jQuery widget
       bCanInspectSelection = false;
    }  
  }

  return bCanInspectSelection;
}

//--------------------------------------------------------------------
// FUNCTION:
//   initializeUI
//
// DESCRIPTION:
//   This is an internal utility function that searches through the
//   Property Inspector document to find all of the UI controls we
//   will programatically manipulate, and stores handles to them in
//   global variables which are used in some of the other functions
//   for this Property Inspector.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

function initializeUI() 
{
	AUTOCOMPLETE_ID = document.getElementById("idInput");
	SOURCE_INPUT = document.getElementById("sourceInput");
	MINLENGTH_INPUT = document.getElementById("minLengthInput");
	DELAY_INPUT = document.getElementById("delayInput");
	APPEND_INPUT = document.getElementById("appendInput");
	AUTOFOCUS_CHECK = document.getElementById("autoFocusCheck");
	MY_LIST = new ListControl("mySelect");
	AT_LIST = new ListControl("atSelect");
	COLLISION_LIST = new ListControl("collisionSelect");
}

//--------------------------------------------------------------------
// FUNCTION:
//   inspectSelection
//
// DESCRIPTION:
//   This is a Property Inspector API function that gets called
//   whenever the selection in the document has changed and it has
//   been decided that this Property Inspector should be displayed.
//   This function syncs up the Property Inspector UI with the
//   widget's design-time object so that it accurately reflects
//   what is in the widget HTML markup and its JS constructor.
//
// ARGUMENTS:
//  None
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------

function inspectSelection() 
{
	dw.logEvent(UT_JQUERY_AUTOCOMPLETE, UT_JQUERY_AUTOCOMPLETE_INSPECT);
	// Call initializeUI() here; it's how the global variables get
  // initialized. The onLoad event on the body tag is never triggered
  // in inspectors.
  initializeUI();
	
  var dom = dw.getDocumentDOM();
  var selectedNode = dom.getSelectedNode();
  if (!canInspectSelection())
    return;
		
	var inputId = selectedNode.id;
  // Update the ID field in the PI.
  AUTOCOMPLETE_ID.value = inputId;	
	
	var widgetMgr = JQuery.DesignTime.Widget.Manager.getManagerForDocument(dom); 
  
  if (!widgetMgr)
	return;
	
	var ac = widgetMgr.getWidget('autocomplete', inputId);
	
	if (!ac)
	{
		return;
	}
	
	if (ac && ac.recalculateOpts)
		ac.recalculateOpts();
	
	SOURCE_INPUT.value = ac.getSourceValue();
	MINLENGTH_INPUT.value = ac.getMinLengthValue();
	
	if( MINLENGTH_INPUT.value == "" )
		MINLENGTH_INPUT.value = "1";
	
	DELAY_INPUT.value = ac.getDelayValue();
	
	if( DELAY_INPUT.value == "" )
		DELAY_INPUT.value = "300";
	
	APPEND_INPUT.value = ac.getAppendValue();
	
	if( APPEND_INPUT.value == "" )
		APPEND_INPUT.value = "body"; 
	
	AUTOFOCUS_CHECK.checked = ac.getAutoFocusValue();
	
	var myListArray = ac.getMyListArray();
	MY_LIST.setAll(myListArray, myListArray);	
	if( myListArray.length )
		MY_LIST.setIndex(ac.getMyListIndex());
		
	var atListArray = ac.getAtListArray();
	AT_LIST.setAll(atListArray, atListArray);	
	if( atListArray.length )
		AT_LIST.setIndex(ac.getAtListIndex());

	var collisionListArray = ac.getCollisionListArray();
	COLLISION_LIST.setAll(collisionListArray, collisionListArray);	
	if( collisionListArray.length )
		COLLISION_LIST.setIndex(ac.getCollisionListIndex());	
}


//--------------------------------------------------------------------
// FUNCTION:
//   updateTag
//
// DESCRIPTION:
//   This function handles all of the user actions triggered by the
//   user from the Propery Inspector controls.
//
// ARGUMENTS:
//  action - string - The name of the action to perform.
//
// RETURNS:
//   N/A
//--------------------------------------------------------------------
function updateTag(action)
{
	var dom = dw.getDocumentDOM();
	var selectedNode = dom.getSelectedNode();
	if (!canInspectSelection())
		return;
	  
	var inputId = selectedNode.id;
	  
	if (!inputId)
		return;
	  
	var widgetMgr = JQuery.DesignTime.Widget.Manager.getManagerForDocument(dom); 
	var autocomplete = widgetMgr.getWidget('autocomplete', inputId );
	if ( !autocomplete )
		return;
		
	if (action)
	{
		switch (action)
		{
			case "id":
			{
			// Validate the new id.
        var newId = AUTOCOMPLETE_ID.value;
        if ( newId == inputId )
          return; // Nothing to change.
        
        if ( newId.length == 0 )
        {
          alert(dw.loadString("jquery/widget/alert/need unique id"));
          return;
        }
        
        if ( dom.getElementById(newId) )
        {
          alert(dw.loadString("jquery/widget/alert/id already exists"));
          return;
        }
        
        if ( !dwscripts.isValidID(newId) )
        {
          alert(dw.loadString("jquery/widget/alert/id is invalid"));
          return;
        }
        
        // Update the constructor.
        autocomplete.updateWidgetId(newId);

        // Update the WidgetManager for the new ID.
        widgetMgr.setWidget('autocomplete', newId, autocomplete );
			}
			break;
			case "setSource":
			{
				var sourceVal = SOURCE_INPUT.value.toString();
				var checkedSource = isEnclosedBy(sourceVal,'[',']');
				
				if (checkedSource)
				{
					var arrayVals = checkedSource.split(',');
					
					for (var i = 0; i < arrayVals.length; i++)
					{
						if (!isEnclosedBy(arrayVals[i], '"', '"'))
						{
							autocomplete.setSourceValue("");
							autocomplete.refresh();
							dom.setSelectedNode(selectedNode); 
							inspectSelection();
							return;	
						}
					}
					
					try
					{
						var sourceArray = eval(sourceVal);
						autocomplete.setSourceArray(sourceArray);
					}
					catch(e)
					{
						autocomplete.setSourceValue("");
						autocomplete.refresh();
						dom.setSelectedNode(selectedNode); 
						inspectSelection();
					}
				}
				//This is a string URL for autocomplete source
				else							
				{
					SOURCE_INPUT.value = sourceVal.replace(/"|'/g,'');
					autocomplete.setSourceValue(SOURCE_INPUT.value);
				}
			}
			break;
			case "setMinLength":
			{
				autocomplete.setMinLengthValue(MINLENGTH_INPUT.value);
			}
			break;
			case "setDelay":
			{
				autocomplete.setDelayValue(DELAY_INPUT.value);
			}
			break;
			case "setAppend":
			{
				autocomplete.setAppendValue(APPEND_INPUT.value);
			}
			break;
			case "setAutoFocus":
			{
				autocomplete.setAutoFocusValue(AUTOFOCUS_CHECK.checked);
			}
			break;
			case "setMy":
			{
				autocomplete.setMyValue(MY_LIST.getIndex());
			}
			break;
			case "setAt":
			{
				autocomplete.setAtValue(AT_LIST.getIndex());
			}
			break;
			case "setCollision":
			{
				autocomplete.setCollisionValue(COLLISION_LIST.getIndex());
			}
			break;
			
			
		}
	}
	
  autocomplete.refresh();
  
	//Make sure the selection stays intact
  dom.setSelectedNode(selectedNode); 
  inspectSelection();
  //we need to refresh live view after doing this, as partial refresh will not be suffiecient to show the changes!
  dw.reloadLiveView();
}

function isEnclosedBy(str, startChar, endChar)
{
	if (!str)
		return;
		
	var startIndex = -1,
			endIndex = -1;
					
	for (var i = 0; i < str.length; i++)
	{
		if (str.charAt(i) == ' ')
			continue;
		
		if (str.charAt(i) != startChar)
		{
			if (startChar == '"')
			{
				if (str.charAt(i) != "'")
				{
					return null;
				}
				else
				{
					startIndex = i;
					break;	
				}
			}
			else
			{
				return null;
			}
		}	
		else
		{
			startIndex = i;
			break;	
		}
	}	
	
	for (i = str.length-1; i >= 0; i--)
	{
		if (str.charAt(i) == ' ')
			continue;
		
		if (str.charAt(i) != endChar)
		{
			if (endChar == '"')
			{
				if (str.charAt(i) != "'")
					return null;
				else
				{
					endIndex = i;
					break;	
				}	
			}
			else
			{
				return null;
			}
		}	
		else
		{
			endIndex = i;
			break;	
		}	
	}	
	
	if (startIndex != -1 && endIndex != -1)
		return str.slice(startIndex+1, endIndex);
	else	
		return null;
}

function browseForSource()
{
	var browseTitle = dw.loadString("Inspectors/jquery_autocomplete/browseSourceTitle");
	var supportedFileTypes = new Array("*.json; *.js");
	
	var filename = 	dw.browseForFileURL("select", browseTitle, false, false, supportedFileTypes);
	if (filename)
	{
		SOURCE_INPUT.value = filename;
		updateTag('setSource');
	}
}