public class TagsWidget extends Menu {
	final TagsDS tagsDS = TagsDS.getInstance();

	public TagsWidget() {

		tagsDS.setRecordXPath("//Tag");
		tagsDS.setFetchDataURL("restlet/sigs/ui/tags");

		refreshMenuList();

		this.addCellClickHandler(new CellClickHandler() {

			public void onCellClick(CellClickEvent event) {
				String title = event.getRecord().getAttribute("title");
				String checked = event.getRecord().getAttribute("checked");

				//If user wants to add a New Tag..
				if (title.equalsIgnoreCase("New Tag")) {
					if(SearchTabWidget.grid.getSelection().length > 0)
					{
						SC.askforValue("New Tag", "Enter new tag",
							new ValueCallback() {
							public void execute(String value) {
								if(value!=null)
									updateSignatureTags(value,"ADD"); //Let the user add a new tag to the selected signatures
							}
						});
					}
					else
					{
						SC.say("Select Signature to be tagged first");
					}
				}
				else{
					if(checked!=null && checked.equals("true")){
						//If the tag is already checked and the user clicks on it,
						//then it would mean he no longer wants the records to have that tag..
						//basically unchecking it
						updateSignatureTags(title,"REMOVE");
					}
					else{
						//If not already checked then add the selected to those records in the grid
						updateSignatureTags(title,"ADD");
					}
				}
			}
		});

		SearchTabWidget.grid.addSelectionChangedHandler(new SelectionChangedHandler() {

			public void onSelectionChanged(SelectionEvent event) {
				ListGridRecord[] listGrRec = SearchTabWidget.grid.getSelection();
				ArrayList<String> tagsList = new ArrayList<String>();

				/* For every selected record in the grid, if the record has a tag then
				its value is retrieved and the corresponding tag in the menu item is checked.
				so that the user already knows that the tag exists on that record already.
				*/
				for (ListGridRecord lgr : listGrRec) {
					String val = lgr.getAttribute("tags");

					if(val!="")
					{
						String[] temp = val.split(",");
						for(int i=0;i<temp.length;i++)
						{
							if((temp[i]!="") && !(tagsList.contains(temp[i])))
							{
								tagsList.add(temp[i]);
							}
						}
					}
				}

				MenuItem tagItems[] = getItems();
				if(!tagsList.isEmpty())
				{
					for(int i=0;i<tagItems.length;i++)
					{
						MenuItem taggedItem = getItem(i);
						if(tagsList.contains(tagItems[i].getTitle()))
						{
							taggedItem.setChecked(true);
						}
						else{
							taggedItem.setChecked(false);
						}
						tagItems[i] = taggedItem;
					}
				}
				else
				{
					for(int i=0;i<tagItems.length;i++)
					{
						tagItems[i].setChecked(false);
					}
				}
				setItems(tagItems);
			}
		});
	}

	void refreshMenuList()
	{
		final MenuItem[] itemArr = new MenuItem[10];
		final MenuItemSeparator separator = new MenuItemSeparator();

		/* Since I have a DS for retreiving the tags existing in the DB,
		this function handles refreshing the tag list wenever user adds or removes tags from
		the records.
		*/
		tagsDS.fetchData(new Criteria(), new DSCallback() {

			public void execute(DSResponse response, Object rawData,
					DSRequest request) {

				JsArray<JavaScriptObject> arrJso = ((JavaScriptObject) rawData).cast();
				int i=0;
				if(arrJso.length() > 0)
				{
					for (i = 0; i < arrJso.length(); i++) {
						String tagTitle = JSOHelper.getAttribute(arrJso.get(i), "tags");
						itemArr[i] = new MenuItem(tagTitle);
					}
					// Add seperator between DB tags and New tag at the end of the list.
					itemArr[i] = separator;
					itemArr[i+1] = new MenuItem("New Tag");
					setItems(itemArr);
				}
				else
					setItems(new MenuItem("New tag"));
			}
		});
	}

	// This function takes care of updating the DB with the tags assigned by the user.
	void updateSignatureTags(String value, String operation)
	{
		if (SearchTabWidget.grid.getSelection() != null) {
			for (ListGridRecord lgr : SearchTabWidget.grid.getSelection()) {
				lgr.setAttribute("TagOperation",operation ); // Since tags is not a part of the same DS as the grid
				lgr.setAttribute("Tag", value);
				SearchTabWidget.grid.updateData(lgr, new DSCallback(){

					public void execute(DSResponse response, Object rawData,
							DSRequest request) {
						SearchTabWidget.grid.invalidateCache();
						refreshMenuList();
					}
				});
			}
		}
	}
}
