//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::cleanupClass()
{
	// This is no longer necessary, since the list is no longer smart pointers.
#if 0
	while(!sViewerMediaImplList.empty())
	{
		sViewerMediaImplList.pop_back();
	}
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::setVolume(F32 volume)
{
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();

	for(; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		pimpl->setVolume(volume);
	}
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::updateMedia()
{
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();

	for(; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		pimpl->update();
	}
}
/////////////////////////////////////////////////////////////////////////////////////////
// static 
void LLViewerMedia::clearAllCaches()
{
	// Clear all plugins' caches
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();
	for (; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		pimpl->clearCache();
	}
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::removeMedia(LLViewerMediaImpl* media)
{
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();
	
	for(; iter != end; iter++)
	{
		if(media == *iter)
		{
			sViewerMediaImplList.erase(iter);
			return;
		}
	}
}
/////////////////////////////////////////////////////////////////////////////////////////
// static 
void LLViewerMedia::setCookiesEnabled(bool enabled)
{
	// Set the "cookies enabled" flag for all loaded plugins
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();
	for (; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		if(pimpl->mMediaSource)
		{
			pimpl->mMediaSource->enable_cookies(enabled);
		}
	}
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
bool LLViewerMedia::textureHasMedia(const LLUUID& texture_id)
{
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();

	for(; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		if(pimpl->getMediaTextureID() == texture_id)
		{
			return true;
		}
	}
	return false;
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
LLViewerMediaImpl* LLViewerMedia::getMediaImplFromTextureID(const LLUUID& texture_id)
{
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();

	for(; iter != end; iter++)
	{
		LLViewerMediaImpl* media_impl = *iter;
		if(media_impl->getMediaTextureID() == texture_id)
		{
			return media_impl;
		}
	}
	return NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
viewer_media_t LLViewerMedia::newMediaImpl(const std::string& media_url,
														 const LLUUID& texture_id,
														 S32 media_width, S32 media_height, U8 media_auto_scale,
														 U8 media_loop,
														 std::string mime_type)
{
	LLViewerMediaImpl* media_impl = getMediaImplFromTextureID(texture_id);
	if(media_impl == NULL || texture_id.isNull())
	{
		// Create the media impl
		media_impl = new LLViewerMediaImpl(media_url, texture_id, media_width, media_height, media_auto_scale, media_loop, mime_type);
		sViewerMediaImplList.push_back(media_impl);
	}
	else
	{
		media_impl->stop();
		media_impl->mTextureId = texture_id;
		media_impl->mMediaURL = media_url;
		media_impl->mMediaWidth = media_width;
		media_impl->mMediaHeight = media_height;
		media_impl->mMediaAutoScale = media_auto_scale;
		media_impl->mMediaLoop = media_loop;
		if(! media_url.empty())
			media_impl->navigateTo(media_url, mime_type, false);
	}
	return media_impl;
}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::updateBrowserUserAgent()
{
	std::string user_agent = getCurrentUserAgent();
	
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();

	for(; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		if(pimpl->mMediaSource && pimpl->mMediaSource->pluginSupportsMediaBrowser())
		{
			pimpl->mMediaSource->setBrowserUserAgent(user_agent);
		}
	}

}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::updateBrowserUserAgent()
{
	std::string user_agent = getCurrentUserAgent();
	
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();

	for(; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		LLPluginClassMedia* plugin = pimpl->getMediaPlugin();
		if(plugin && plugin->pluginSupportsMediaBrowser())
		{
			plugin->setBrowserUserAgent(user_agent);
		}
	}

}
//////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::updateMedia()
{
	sUpdatedCookies = getCookieStore()->getChangedCookies();
	if(!sUpdatedCookies.empty())
	{
		lldebugs << "updated cookies will be sent to all loaded plugins: " << llendl;
		lldebugs << sUpdatedCookies << llendl;
	}
	
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();

	for(; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		pimpl->update();
	}
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::loadCookieFile()
{
	// build filename for each user
	std::string resolved_filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, PLUGIN_COOKIE_FILE_NAME);

	if (resolved_filename.empty())
	{
		llinfos << "can't get path to plugin cookie file - probably not logged in yet." << llendl;
		return;
	}
	
	// open the file for reading
	llifstream file(resolved_filename);
	if (!file.is_open())
	{
		llwarns << "can't load plugin cookies from file \"" << PLUGIN_COOKIE_FILE_NAME << "\"" << llendl;
		return;
	}
	
	getCookieStore()->readAllCookies(file, true);

	file.close();
	
	// send the clear_cookies message to all loaded plugins
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();
	for (; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		if(pimpl->mMediaSource)
		{
			pimpl->mMediaSource->clear_cookies();
		}
	}
	
}
/////////////////////////////////////////////////////////////////////////////////////////
// static
void LLViewerMedia::clearAllCookies()
{
	// Clear all cookies for all plugins
	impl_list::iterator iter = sViewerMediaImplList.begin();
	impl_list::iterator end = sViewerMediaImplList.end();
	for (; iter != end; iter++)
	{
		LLViewerMediaImpl* pimpl = *iter;
		if(pimpl->mMediaSource)
		{
			pimpl->mMediaSource->clear_cookies();
		}
	}
	
	// Clear all cookies from the cookie store
	getCookieStore()->setAllCookies("");

	// FIXME: this may not be sufficient, since the on-disk cookie file won't get written until some browser instance exits cleanly.
	// It also won't clear cookies for other accounts, or for any account if we're not logged in, and won't do anything at all if there are no webkit plugins loaded.
	// Until such time as we can centralize cookie storage, the following hack should cover these cases:
	
	// HACK: Look for cookie files in all possible places and delete them.
	// NOTE: this assumes knowledge of what happens inside the webkit plugin (it's what adds 'browser_profile' to the path and names the cookie file)
	
	// Places that cookie files can be:
	// <getOSUserAppDir>/browser_profile/cookies
	// <getOSUserAppDir>/first_last/browser_profile/cookies  (note that there may be any number of these!)
	// <getOSUserAppDir>/first_last/plugin_cookies.txt  (note that there may be any number of these!)
	
	std::string base_dir = gDirUtilp->getOSUserAppDir() + gDirUtilp->getDirDelimiter();
	std::string target;
	std::string filename;
	
	lldebugs << "base dir = " << base_dir << llendl;

	// The non-logged-in version is easy
	target = base_dir;
	target += "browser_profile";
	target += gDirUtilp->getDirDelimiter();
	target += "cookies";
	lldebugs << "target = " << target << llendl;
	if(LLFile::isfile(target))
	{
		LLFile::remove(target);
	}
	
	// the hard part: iterate over all user directories and delete the cookie file from each one
	while(gDirUtilp->getNextFileInDir(base_dir, "*_*", filename, false))
	{
		target = base_dir;
		target += filename;
		target += gDirUtilp->getDirDelimiter();
		target += "browser_profile";
		target += gDirUtilp->getDirDelimiter();
		target += "cookies";
		lldebugs << "target = " << target << llendl;
		if(LLFile::isfile(target))
		{	
			LLFile::remove(target);
		}
		
		// Other accounts may have new-style cookie files too -- delete them as well
		target = base_dir;
		target += filename;
		target += gDirUtilp->getDirDelimiter();
		target += PLUGIN_COOKIE_FILE_NAME;
		lldebugs << "target = " << target << llendl;
		if(LLFile::isfile(target))
		{	
			LLFile::remove(target);
		}
	}
	
}