void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
{
	bool needs_update = (getWearableType()==driven_type);

	// if the driver has a driven entry for the passed-in wearable type, we need to refresh the value
	for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
	{
		LLDrivenEntry* driven = &(*iter);
		if (driven && driven->mParam && driven->mParam->getCrossWearable() && driven->mParam->getWearableType() == driven_type)
		{
			needs_update = true;
		}
	}


	if (needs_update)
	{
		LLWearableType::EType driver_type = (LLWearableType::EType)getWearableType();
		
		// If we've gotten here, we've added a new wearable of type "type"
		// Thus this wearable needs to get updates from the driver wearable.
		// The call to setVisualParamWeight seems redundant, but is necessary
		// as the number of driven wearables has changed since the last update. -Nyx
		LLWearable *wearable = mAvatarAppearance->getWearableData()->getTopWearable(driver_type);
		if (wearable)
		{
			wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID));
		}
	}
}
LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
{
	lldebugs << "LLWearableList::createNewWearable()" << llendl;

	LLWearable *wearable = generateNewWearable();
	wearable->setType( type );
	
	std::string name = LLWearableType::getTypeDefaultNewName(wearable->getType());
	wearable->setName( name );

	LLPermissions perm;
	perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
	perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);
	wearable->setPermissions(perm);

	// Description and sale info have default values.
	wearable->setParamsToDefaults();
	wearable->setTexturesToDefaults();

	//mark all values (params & images) as saved
	wearable->saveValues();

	// Send to the dataserver
	wearable->saveNewAsset();


	return wearable;
}
BOOL LLFloaterCustomize::isDirty() const
{
	LLWearableType::EType cur = getCurrentWearableType();
	for(U32 i = 0; i < gAgentWearables.getWearableCount(cur); ++i)
	{
		LLWearable* wearable = gAgentWearables.getWearable(cur,i);
		if(wearable && wearable->isDirty())
			return TRUE;
	}
	return FALSE;
}
// static
void LLFloaterAvatarTextures::onClickDump(void* data)
{
	if (gAgent.isGodlike())
	{
		const LLVOAvatarSelf* avatarp = gAgentAvatarp;
		if (!avatarp) return;
		for (S32 i = 0; i < avatarp->getNumTEs(); i++)
		{
			const LLTextureEntry* te = avatarp->getTE(i);
			if (!te) continue;

			const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)(i));
			if (!tex_entry)
				continue;

			if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))
			{
				LLUUID id = IMG_DEFAULT_AVATAR;
				LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
				if (avatarp->isSelf())
				{
					LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0);
					if (wearable)
					{
						LLLocalTextureObject *lto = wearable->getLocalTextureObject(i);
						if (lto)
						{
							id = lto->getID();
						}
					}
				}
				if (id != IMG_DEFAULT_AVATAR)
				{
					llinfos << "TE " << i << " name:" << tex_entry->mName << " id:" << id << llendl;
				}
				else
				{
					llinfos << "TE " << i << " name:" << tex_entry->mName << " id:" << "<DEFAULT>" << llendl;
				}
			}
			else
			{
				llinfos << "TE " << i << " name:" << tex_entry->mName << " id:" << te->getID() << llendl;
			}
		}
	}
}
LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name)
{
	lldebugs << "LLWearableList::createCopy()" << llendl;

	LLWearable *wearable = generateNewWearable();
	wearable->copyDataFrom(old_wearable);

	LLPermissions perm(old_wearable->getPermissions());
	perm.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true);
	wearable->setPermissions(perm);

	if (!new_name.empty()) wearable->setName(new_name);

	// Send to the dataserver
	wearable->saveNewAsset();

	return wearable;
}
void LLFloaterCustomize::updateInventoryUI()
{
	BOOL all_complete = TRUE;
	BOOL is_complete = FALSE;
	U32 perm_mask = 0x0;
	LLPanelEditWearable* panel;
	LLViewerInventoryItem* item;
	for(S32 i = 0; i < LLWearableType::WT_COUNT; ++i)
	{
		item = NULL;
		panel = mWearablePanelList[i];
		if(panel)
		{
			LLWearable* wearable = panel->getWearable();
			if(wearable)
				item = gInventory.getItem(wearable->getItemID());
		}
		if(item)
		{
			is_complete = item->isComplete();
			if(!is_complete)
			{
				all_complete = FALSE;
			}
			perm_mask = item->getPermissions().getMaskOwner();
		}
		else
		{
			is_complete = false;
			perm_mask = 0x0;
		}
		if(i == sCurrentWearableType)
		{
			if(panel)
			{
				panel->setUIPermissions(perm_mask, is_complete);
			}
			//BOOL is_vis = panel && item && is_complete && (perm_mask & PERM_MODIFY);
			//childSetVisible("panel_container", is_vis);
		}
	}

	childSetEnabled("Make Outfit", all_complete);
}
bool LLFloaterCustomize::onSaveDialog(const LLSD& notification, const LLSD& response )
{
	S32 option = LLNotification::getSelectedOption(notification, response);

	BOOL proceed = FALSE;
	LLWearableType::EType cur = getCurrentWearableType();

	for(U32 i = 0;i < gAgentWearables.getWearableCount(cur);++i)
	{
		LLWearable* wearable = gAgentWearables.getWearable(cur,i);
		if(wearable && wearable->isDirty())
		{
			switch( option )
			{
			case 0:  // "Save"
				gAgentWearables.saveWearable( cur, i );
				proceed = TRUE;
				break;

			case 1:  // "Don't Save"
				{
					gAgentWearables.revertWearable( cur, i );
					proceed = TRUE;
				}
				break;

			case 2: // "Cancel"
				break;

			default:
				llassert(0);
				break;
			}
		}
	}


	mNextStepAfterSaveCallback(proceed);
	mNextStepAfterSaveCallback.disconnect_all_slots();	//Should this be done?

	return false;
}
static void update_texture_ctrl(LLVOAvatar* avatarp,
								 LLTextureCtrl* ctrl,
								 ETextureIndex te)
{
	LLUUID id = IMG_DEFAULT_AVATAR;
	const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture(te);
	if (tex_entry->mIsLocalTexture)
	{
		if (avatarp->isSelf())
		{
			const LLWearableType::EType wearable_type = tex_entry->mWearableType;
			LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0);
			if (wearable)
			{
				LLLocalTextureObject *lto = wearable->getLocalTextureObject(te);
				if (lto)
				{
					id = lto->getID();
				}
			}
		}
	}
	else
	{
		id = avatarp->getTE(te)->getID();
	}
	//id = avatarp->getTE(te)->getID();
	if (id == IMG_DEFAULT_AVATAR)
	{
		ctrl->setImageAssetID(LLUUID::null);
		ctrl->setToolTip(tex_entry->mName + " : " + std::string("IMG_DEFAULT_AVATAR"));
	}
	else
	{
		ctrl->setImageAssetID(id);
		ctrl->setToolTip(tex_entry->mName + " : " + id.asString());
	}
}
// static
void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID& uuid, void* userdata, S32 status, LLExtStat ext_status )
{
	BOOL isNewWearable = FALSE;
	LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
	LLWearable* wearable = NULL; // NULL indicates failure
	
	if( !filename )
	{
		LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;
	}
	else if (status >= 0)
	{
		// read the file
		LLFILE* fp = LLFile::fopen(std::string(filename), "rb");		/*Flawfinder: ignore*/
		if( !fp )
		{
			LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;
		}
		else
		{
			wearable = new LLWearable(uuid);
			bool res = wearable->importFile( fp );
			if (!res)
			{
				if (wearable->getType() == LLWearableType::WT_COUNT)
				{
					isNewWearable = TRUE;
				}
				delete wearable;
				wearable = NULL;
			}

			fclose( fp );
			if(filename)
			{
				LLFile::remove(std::string(filename));
			}
		}
	}
	else
	{
		if(filename)
		{
			LLFile::remove(std::string(filename));
		}
		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );

		LL_WARNS("Wearable") << "Wearable download failed: " << LLAssetStorage::getErrorString( status ) << " " << uuid << LL_ENDL;
		switch( status )
		{
		  case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE:
		  {
			  // Fail
			  break;
		}
		  default:
		{
			  static const S32 MAX_RETRIES = 3;
			  if (data->mRetries < MAX_RETRIES)
			  {
			  // Try again
				  data->mRetries++;
			  gAssetStorage->getAssetData(uuid,
										  data->mAssetType,
										  LLWearableList::processGetAssetReply,
										  userdata);  // re-use instead of deleting.
			  return;
		}
			  else
			  {
				  // Fail
				  break;
			  }
		  }
	}
	}

	if (wearable) // success
	{
		LLWearableList::instance().mList[ uuid ] = wearable;
		LL_DEBUGS("Wearable") << "processGetAssetReply()" << LL_ENDL;
		LL_DEBUGS("Wearable") << wearable << LL_ENDL;
	}
	else
	{
		LLSD args;
		// *TODO:translate
		args["TYPE"] = LLAssetType::lookupHumanReadable(data->mAssetType);
		if (isNewWearable)
		{
			LLNotificationsUtil::add("InvalidWearable");
		}
		else if (data->mName.empty())
		{
			LLNotificationsUtil::add("FailedToFindWearableUnnamed", args);
		}
		else
		{
			args["DESC"] = data->mName;
			LLNotificationsUtil::add("FailedToFindWearable", args);
		}
	}
	// Always call callback; wearable will be NULL if we failed
	{
		if( data->mCallback )
		{
			data->mCallback( wearable, data->mUserdata );
		}
	}
	delete data;
}
void ImportTracker::send_inventory(LLSD& prim)
{
	U32 local_id = prim["LocalID"].asInteger();
	if (prim.has("inventory"))
	{
		std::string assetpre = asset_dir + gDirUtilp->getDirDelimiter();
		LLSD inventory = prim["inventory"];
		for (LLSD::array_iterator inv = inventory.beginArray(); inv != inventory.endArray(); ++inv)
		{
			LLSD item = (*inv);
			InventoryImportInfo* data = new InventoryImportInfo;
			data->localid = local_id;
			LLTransactionID tid;
			tid.generate();
			LLUUID assetid = tid.makeAssetID(gAgent.getSecureSessionID());
			data->tid = tid;
			data->assetid = assetid;
			data->type = LLAssetType::lookup(item["type"].asString());////LLAssetType::EType(U32(item["type"].asInteger()));
			data->name = item["name"].asString();
			data->description = item["desc"].asString();
			if(item.has("item_id"))
			{
				//cmdline_printchat("item id found");
				std::string filename = assetpre + item["item_id"].asString() + "." + item["type"].asString();
				//S32 file_size;
				//LLAPRFile infile ;
				//infile.open(filename, LL_APR_RB, NULL, &file_size);
				//apr_file_t* fp = infile.getFileHandle();
				//if(fp)
				if(LLFile::isfile(filename))
				{
					//cmdline_printchat("file "+filename+" exists");
					data->filename = filename;
					//infile.close();
				}else
				{
					//cmdline_printchat("file "+filename+" does not exist");
					delete data;
					continue;
				}
			}else
			{
				//cmdline_printchat("item id not found");
				delete data;
				continue;
			}

			data->wear_type = NOT_WEARABLE;

			//if(data->type == LLAssetType::AT_LSL_TEXT)
			{
				data->inv_type = LLInventoryType::defaultForAssetType(data->type);
				//printchat("is script");
				data->compiled = false;
				//
				switch(data->type)
				{
				case LLAssetType::AT_TEXTURE:
				case LLAssetType::AT_TEXTURE_TGA:
					//cmdline_printchat("case textures");
					{
						std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
						S32 file_size;
						LLAPRFile infile ;
						infile.open(data->filename, LL_APR_RB, NULL, &file_size);
						if (infile.getFileHandle())
						{
							//cmdline_printchat("got file handle");
							LLVFile file(gVFS, data->assetid, data->type, LLVFile::WRITE);
							file.setMaxSize(file_size);
							const S32 buf_size = 65536;
							U8 copy_buf[buf_size];
							while ((file_size = infile.read(copy_buf, buf_size)))
							{
								file.write(copy_buf, file_size);
							}
							LLSD body;
							body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
							body["asset_type"] = LLAssetType::lookup(data->type);
							body["inventory_type"] = LLInventoryType::lookup(data->inv_type);
							body["name"] = data->name;
							body["description"] = data->description;
							body["next_owner_mask"] = LLSD::Integer(U32_MAX);
							body["group_mask"] = LLSD::Integer(U32_MAX);
							body["everyone_mask"] = LLSD::Integer(U32_MAX);
							body["expected_upload_cost"] = LLSD::Integer(LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
							//cmdline_printchat("posting "+ data->assetid.asString());
							LLHTTPClient::post(url, body, new JCImportInventoryResponder(body, data->assetid, data->type,data));
							//error = TRUE;
						}
					}
					break;
				case LLAssetType::AT_CLOTHING:
				case LLAssetType::AT_BODYPART:
					//cmdline_printchat("case cloth/bodypart");
					{
						S32 file_size;
						LLAPRFile infile ;
						infile.open(data->filename, LL_APR_RB, NULL, &file_size);
						if (infile.getFileHandle())
						{
							//cmdline_printchat("got file handle @ cloth");
							LLVFile file(gVFS, data->assetid, data->type, LLVFile::WRITE);
							file.setMaxSize(file_size);
							const S32 buf_size = 65536;
							U8 copy_buf[buf_size];
							while ((file_size = infile.read(copy_buf, buf_size)))
							{
								file.write(copy_buf, file_size);
							}

							LLFILE* fp = LLFile::fopen(data->filename, "rb");
							if(fp)//HACK LOL LOL LOL
							{
								LLWearable* wearable = new LLWearable(LLUUID::null);
								wearable->importFile( fp );
								//if (!res)
								{
									data->wear_type = wearable->getType();
								}
								delete wearable;
							}
							//cmdline_printchat("storing "+data->assetid.asString());
							gAssetStorage->storeAssetData(data->tid, data->type,
												JCImportInventorycallback,
												(void*)data,
												FALSE,
												TRUE,
												FALSE);
						}
					}
					break;
				case LLAssetType::AT_NOTECARD:
					//cmdline_printchat("case notecard");
					{
						//std::string agent_url = gAgent.getRegion()->getCapability("UpdateNotecardAgentInventory");
						LLPointer<LLInventoryCallback> cb = new JCPostInvCallback(data);
						LLPermissions perm;
						LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
						create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
							gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH), data->tid, data->name,
							data->description, data->type, LLInventoryType::defaultForAssetType(data->type), data->wear_type,
							LLFloaterPerms::getNextOwnerPerms(),
							cb);
					}
					break;
				case LLAssetType::AT_LSL_TEXT:
					{
						LLPointer<LLInventoryCallback> cb = new JCPostInvCallback(data);
						LLPermissions perm;
						LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
						create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
							gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH), data->tid, data->name,
							data->description, data->type, LLInventoryType::defaultForAssetType(data->type), data->wear_type,
							LLFloaterPerms::getNextOwnerPerms(),
							cb);
					}
					break;
				case LLAssetType::AT_SCRIPT://this shouldn't happen as this is legacy shit
				case LLAssetType::AT_GESTURE://we don't import you atm...
				default:
					break;
				}
				asset_insertions += 1;
			}
		}
	}
}