// static
void LLFloaterExploreSounds::handle_stop(void* user_data)
{
	LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data;
	LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("sound_list");
	std::vector<LLScrollListItem*> selection = list->getAllSelected();
	std::vector<LLScrollListItem*>::iterator selection_iter = selection.begin();
	std::vector<LLScrollListItem*>::iterator selection_end = selection.end();
	std::vector<LLUUID> asset_list;
	for( ; selection_iter != selection_end; ++selection_iter)
	{
		LLSoundHistoryItem item = floater->getItem((*selection_iter)->getValue());
		if(item.mID.isNull()) continue;
		if(item.mPlaying)
		{
			if(item.mAudioSource)
			{
				S32 type = item.mType;
				item.mAudioSource->setType(LLAudioEngine::AUDIO_TYPE_UI);
				if(item.mAudioSource)
					item.mAudioSource->play(LLUUID::null);
				if(item.mAudioSource)
					item.mAudioSource->setType(type);
			}
		}
	}
}
// static
void LLFloaterExploreSounds::handle_look_at(void* user_data)
{
	LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data;
	LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("sound_list");
	LLUUID selection = list->getSelectedValue().asUUID();
	LLSoundHistoryItem item = floater->getItem(selection); // Single item only
	if(item.mID.isNull()) return;

	LLVector3d pos_global = item.mPosition;

	// Try to find object position
	if(item.mSourceID.notNull())
	{
		LLViewerObject* object = gObjectList.findObject(item.mSourceID);
		if(object)
		{
			pos_global = object->getPositionGlobal();
		}
	}

	// Move the camera
	// Find direction to self (reverse)
	LLVector3d cam = gAgent.getPositionGlobal() - pos_global;
	cam.normalize();
	// Go 4 meters back and 3 meters up
	cam *= 4.0f;
	cam += pos_global;
	cam += LLVector3d(0.f, 0.f, 3.0f);

	gAgent.setFocusOnAvatar(FALSE, FALSE);
	gAgent.setCameraPosAndFocusGlobal(cam, pos_global, item.mSourceID);
	gAgent.setCameraAnimating(FALSE);
}
// static
void LLFloaterExploreSounds::handle_play_in_world(void* user_data)
{
	LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data;
	LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("sound_list");
	std::vector<LLScrollListItem*> selection = list->getAllSelected();
	std::vector<LLScrollListItem*>::iterator selection_iter = selection.begin();
	std::vector<LLScrollListItem*>::iterator selection_end = selection.end();
	for( ; selection_iter != selection_end; ++selection_iter)
	{
		LLSoundHistoryItem item = floater->getItem((*selection_iter)->getValue());
		if(item.mID.isNull()) continue;

		LLMessageSystem* msg = gMessageSystem;
		msg->newMessageFast(_PREHASH_SoundTrigger);
		msg->nextBlockFast(_PREHASH_SoundData);
		msg->addUUIDFast(_PREHASH_SoundID, item.mAssetID);
		// Client untrusted, ids set on sim
		msg->addUUIDFast(_PREHASH_OwnerID, LLUUID::null );
		msg->addUUIDFast(_PREHASH_ObjectID, LLUUID::null );
		msg->addUUIDFast(_PREHASH_ParentID, LLUUID::null );
		msg->addU64Fast(_PREHASH_Handle, gAgent.getRegion()->getHandle());
		LLVector3 position = gAgent.getPositionAgent();
		msg->addVector3Fast(_PREHASH_Position, position);
		msg->addF32Fast(_PREHASH_Gain, 1.0f);

		gAgent.sendMessage();
	}
}
void LLFloaterExploreSounds::blacklistSound(void* user_data)
{
	LLFloaterBlacklist::show();
	LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data;
	LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("sound_list");

	typedef std::vector<LLScrollListItem*> item_map_t;
	item_map_t selection = list->getAllSelected();
	item_map_t::iterator selection_end = selection.end();
	
	for(item_map_t::iterator selection_iter = selection.begin(); selection_iter != selection_end; ++selection_iter)
	{
		LLSoundHistoryItem item = floater->getItem((*selection_iter)->getValue());
		if(item.mID.isNull()) continue;

		LLSD sound_data;
		std::string agent;
		gCacheName->getFullName(item.mOwnerID, agent);
		LLViewerRegion* cur_region = gAgent.getRegion();

		if(cur_region)
		  sound_data["entry_name"] = llformat("Sound played by %s in region %s",agent.c_str(),cur_region->getName().c_str());
		else
		  sound_data["entry_name"] = llformat("Sound played by %s",agent.c_str());
		sound_data["entry_type"] = (LLAssetType::EType)item.mType;
		sound_data["entry_agent"] = gAgent.getID();
		LLFloaterBlacklist::addEntry(item.mAssetID,sound_data);
	}
}
// static
void LLFloaterExploreSounds::handle_copy_uuid(void* user_data)
{
	LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data;
	LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("sound_list");
	LLUUID selection = list->getSelectedValue().asUUID(); // Single item only
	LLSoundHistoryItem item = floater->getItem(selection);
	if(item.mID.isNull()) return;

	gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(item.mAssetID.asString()));
}
// static
void LLFloaterExploreSounds::handle_copy_uuid(void* user_data)
{
	LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data;
	LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("sound_list");
	LLUUID selection = list->getSelectedValue().asUUID(); // Single item only
	LLSoundHistoryItem item = floater->getItem(selection);
	if(item.mID.isNull()) return;

	if (item.mOwnerID == gAgent.getID())
	{
		gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(item.mAssetID.asString()));
	}
	else
	{
		LLChat chat;
		chat.mSourceType = CHAT_SOURCE_SYSTEM;
		chat.mText = llformat("Can't copy UUIDs you don't own.");
		LLFloaterChat::addChat(chat);
	}
}
// static
void LLFloaterExploreSounds::handle_play_locally(void* user_data)
{
	LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data;
	LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("sound_list");
	std::vector<LLScrollListItem*> selection = list->getAllSelected();
	std::vector<LLScrollListItem*>::iterator selection_iter = selection.begin();
	std::vector<LLScrollListItem*>::iterator selection_end = selection.end();
	std::vector<LLUUID> asset_list;
	for( ; selection_iter != selection_end; ++selection_iter)
	{
		LLSoundHistoryItem item = floater->getItem((*selection_iter)->getValue());
		if(item.mID.isNull()) continue;
		// Unique assets only
		if(std::find(asset_list.begin(), asset_list.end(), item.mAssetID) == asset_list.end())
		{
			asset_list.push_back(item.mAssetID);
			gAudiop->triggerSound(item.mAssetID, LLUUID::null, 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
		}
	}
}
// static
void LLFloaterExploreSounds::handle_open(void* user_data)
{
	LLFloaterExploreSounds* floater = (LLFloaterExploreSounds*)user_data;
	LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("sound_list");
	std::vector<LLScrollListItem*> selection = list->getAllSelected();
	std::vector<LLScrollListItem*>::iterator selection_iter = selection.begin();
	std::vector<LLScrollListItem*>::iterator selection_end = selection.end();
	std::vector<LLUUID> asset_list;
	for( ; selection_iter != selection_end; ++selection_iter)
	{
		LLSoundHistoryItem item = floater->getItem((*selection_iter)->getValue());
		if(item.mID.isNull()) continue;
		// Unique assets only
		if(std::find(asset_list.begin(), asset_list.end(), item.mAssetID) == asset_list.end())
		{
			asset_list.push_back(item.mAssetID);
			LLUUID inv_item = LLLocalInventory::addItem(item.mAssetID.asString(), LLAssetType::AT_SOUND, item.mAssetID, true);
		}
	}
}