/* Parse a ReplayGain tag conforming to the "VorbisGain standard". If a
 * valid tag is found, update mp3entry struct accordingly. Existing values 
 * are not overwritten.
 *
 * key     Name of the tag.
 * value   Value of the tag.
 * entry   mp3entry struct to update.
 */
void parse_replaygain(const char* key, const char* value, 
                      struct mp3entry* entry)
{
    if (((strcasecmp(key, "replaygain_track_gain") == 0) || 
         (strcasecmp(key, "rg_radio") == 0)) && 
        !entry->track_gain)
    {
        entry->track_level = get_replaygain(value);
        entry->track_gain  = convert_gain(entry->track_level);
    }
    else if (((strcasecmp(key, "replaygain_album_gain") == 0) || 
              (strcasecmp(key, "rg_audiophile") == 0)) && 
             !entry->album_gain)
    {
        entry->album_level = get_replaygain(value);
        entry->album_gain  = convert_gain(entry->album_level);
    }
    else if (((strcasecmp(key, "replaygain_track_peak") == 0) || 
              (strcasecmp(key, "rg_peak") == 0)) && 
             !entry->track_peak)
    {
        entry->track_peak = get_replaypeak(value);
    }
    else if ((strcasecmp(key, "replaygain_album_peak") == 0) && 
             !entry->album_peak)
    {
        entry->album_peak = get_replaypeak(value);
    }
}
void file_info::merge(const pfc::list_base_const_t<const file_info*> & p_in)
{
	t_size in_count = p_in.get_count();
	if (in_count == 0)
	{
		meta_remove_all();
		return;
	}
	else if (in_count == 1)
	{
		const file_info * info = p_in[0];

		copy_meta(*info);

		set_replaygain(replaygain_info::g_merge(get_replaygain(),info->get_replaygain()));

		overwrite_info(*info);

		//copy_info_single_by_name(*info,"tagtype");
		
		return;
	}
	
	merge_meta(*this,p_in);

	{
		pfc::string8_fastalloc tagtype;
		replaygain_info rg = get_replaygain();
		t_size in_ptr;
		for(in_ptr = 0; in_ptr < in_count; in_ptr++ )
		{
			const file_info * info = p_in[in_ptr];
			rg = replaygain_info::g_merge(rg, info->get_replaygain());
			t_size field_ptr, field_max = info->info_get_count();
			for(field_ptr = 0; field_ptr < field_max; field_ptr++ )
			{
				const char * field_name = info->info_enum_name(field_ptr), * field_value = info->info_enum_value(field_ptr);
				if (*field_value)
				{
					if (!pfc::stricmp_ascii(field_name,"tagtype"))
					{
						if (!tagtype.is_empty()) tagtype += "|";
						tagtype += field_value;
					}
				}
			}
		}
		if (!tagtype.is_empty()) info_set("tagtype",tagtype);
		set_replaygain(rg);
	}
}
/* Parse a ReplayGain tag conforming to the "VorbisGain standard". If a
 * valid tag is found, update mp3entry struct accordingly. Existing values 
 * are not overwritten. Returns number of bytes written to buffer.
 *
 * key     Name of the tag.
 * value   Value of the tag.
 * entry   mp3entry struct to update.
 * buffer  Where to store the text for gain values (for later display).
 * length  Bytes left in buffer.
 */
long parse_replaygain(const char* key, const char* value,
    struct mp3entry* entry, char* buffer, int length)
{
    char **p = NULL;

    if (((strcasecmp(key, "replaygain_track_gain") == 0)
        || (strcasecmp(key, "rg_radio") == 0)) && !entry->track_gain)
    {
        entry->track_gain = get_replaygain(value);
        p = &(entry->track_gain_string);
    }
    else if (((strcasecmp(key, "replaygain_album_gain") == 0)
        || (strcasecmp(key, "rg_audiophile") == 0)) && !entry->album_gain)
    {
        entry->album_gain = get_replaygain(value);
        p = &(entry->album_gain_string);
    }
    else if (((strcasecmp(key, "replaygain_track_peak") == 0)
        || (strcasecmp(key, "rg_peak") == 0)) && !entry->track_peak)
    {
        entry->track_peak = get_replaypeak(value);
    }
    else if ((strcasecmp(key, "replaygain_album_peak") == 0)
        && !entry->album_peak)
    {
        entry->album_peak = get_replaypeak(value);
    }

    if (p)
    {
        int len = strlen(value);

        len = MIN(len, length - 1);

        /* A few characters just isn't interesting... */
        if (len > 1)
        {
            strlcpy(buffer, value, len + 1);
            *p = buffer;
            return len + 1;
        }
    }

    return 0;
}
bool file_info::info_set_replaygain_ex(const char * p_name,t_size p_name_len,const char * p_value,t_size p_value_len)
{
    replaygain_info temp = get_replaygain();
    if (temp.set_from_meta_ex(p_name,p_name_len,p_value,p_value_len))
    {
        set_replaygain(temp);
        return true;
    }
    else return false;
}
void file_info::merge_fallback(const file_info & source) {
	set_replaygain( replaygain_info::g_merge(get_replaygain(), source.get_replaygain() ) );
	if (get_length() <= 0) set_length(source.get_length());
	t_size count = source.info_get_count();
	for(t_size infoWalk = 0; infoWalk < count; ++infoWalk) {
		const char * name = source.info_enum_name(infoWalk);
		if (!info_exists(name)) __info_add_unsafe(name, source.info_enum_value(infoWalk));
	}
	count = source.meta_get_count();
	for(t_size metaWalk = 0; metaWalk < count; ++metaWalk) {
		const char * name = source.meta_enum_name(metaWalk);
		if (!meta_exists(name)) _copy_meta_single_nocheck(source, metaWalk);
	}
}
void file_info::info_set_replaygain_track_peak(float value)
{
    replaygain_info temp = get_replaygain();
    temp.m_track_peak = value;
    set_replaygain(temp);
}
void file_info::info_set_replaygain_album_gain(float value)
{
    replaygain_info temp = get_replaygain();
    temp.m_album_gain = value;
    set_replaygain(temp);
}