/*
 * Copyright 2003 Vincent Béron
 * Copyright 2007, 2008 Mikolaj Zalewski
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include "dumpres.h"
#include "utils.h"
#include "wrc.h"

#define MASTER_LANGUAGE LANG_ENGLISH
#define MASTER_SUBLANGUAGE SUBLANG_ENGLISH_US
#define NB_LANG 0x94

enum lang_type_e {
	lang_type_master = 0,
	lang_type_neutral,
	lang_type_normal
};

static language_t get_language(resource_t *resource) {
	switch(resource->type) {
		case res_acc:
			return *resource->res.acc->lvc.language;
		case res_bmp:
			return *resource->res.bmp->data->lvc.language;
		case res_cur:
			return *resource->res.cur->lvc.language;
		case res_curg:
			return *resource->res.curg->lvc.language;
		case res_dlg:
			return *resource->res.dlg->lvc.language;
		case res_fnt:
			return *resource->res.fnt->data->lvc.language;
		case res_fntdir:
			return *resource->res.fnd->data->lvc.language;
		case res_ico:
			return *resource->res.ico->lvc.language;
		case res_icog:
			return *resource->res.icog->lvc.language;
		case res_men:
			return *resource->res.men->lvc.language;
		case res_rdt:
			return *resource->res.rdt->data->lvc.language;
		case res_stt:
			return *resource->res.stt->lvc.language;
		case res_usr:
			return *resource->res.usr->data->lvc.language;
		case res_msg:
			return *resource->res.msg->data->lvc.language;
		case res_ver:
			return *resource->res.ver->lvc.language;
		case res_dlginit:
			return *resource->res.dlgi->data->lvc.language;
		case res_toolbar:
			return *resource->res.tbt->lvc.language;
		case res_anicur:
		case res_aniico:
			return *resource->res.ani->data->lvc.language;
                case res_html:
                        return *resource->res.html->data->lvc.language;
		default:
			/* Not supposed to reach here */
			fprintf(stderr, "Not supposed to reach here (get_language_id())\n");
			abort();
	}
}

static int get_language_id(resource_t *resource) {
    return get_language(resource).id;
}

static int compare_lang(language_t lang1, language_t lang2)
{
    return memcmp(&lang1, &lang2, sizeof(language_t));
}

#if 0

#define PRETTYPRINTLANG(langid) \
	if(LANG_##langid == lid) { \
		return #langid; \
	}

static const char *get_language_name(int lid) {
	PRETTYPRINTLANG(NEUTRAL)
	PRETTYPRINTLANG(AFRIKAANS)
	PRETTYPRINTLANG(ALBANIAN)
	PRETTYPRINTLANG(ARABIC)
	PRETTYPRINTLANG(ARMENIAN)
	PRETTYPRINTLANG(ASSAMESE)
	PRETTYPRINTLANG(AZERI)
	PRETTYPRINTLANG(BASQUE)
	PRETTYPRINTLANG(BELARUSIAN)
	PRETTYPRINTLANG(BENGALI)
	PRETTYPRINTLANG(BULGARIAN)
	PRETTYPRINTLANG(CATALAN)
	PRETTYPRINTLANG(CHINESE)
	PRETTYPRINTLANG(CROATIAN)
	PRETTYPRINTLANG(CZECH)
	PRETTYPRINTLANG(DANISH)
	PRETTYPRINTLANG(DIVEHI)
	PRETTYPRINTLANG(DUTCH)
	PRETTYPRINTLANG(ENGLISH)
	PRETTYPRINTLANG(ESTONIAN)
	PRETTYPRINTLANG(FAEROESE)
	PRETTYPRINTLANG(FARSI)
	PRETTYPRINTLANG(FINNISH)
	PRETTYPRINTLANG(FRENCH)
	PRETTYPRINTLANG(GALICIAN)
	PRETTYPRINTLANG(GEORGIAN)
	PRETTYPRINTLANG(GERMAN)
	PRETTYPRINTLANG(GREEK)
	PRETTYPRINTLANG(GUJARATI)
	PRETTYPRINTLANG(HEBREW)
	PRETTYPRINTLANG(HINDI)
	PRETTYPRINTLANG(HUNGARIAN)
	PRETTYPRINTLANG(ICELANDIC)
	PRETTYPRINTLANG(INDONESIAN)
	PRETTYPRINTLANG(ITALIAN)
	PRETTYPRINTLANG(JAPANESE)
	PRETTYPRINTLANG(KANNADA)
	PRETTYPRINTLANG(KASHMIRI)
	PRETTYPRINTLANG(KAZAK)
	PRETTYPRINTLANG(KONKANI)
	PRETTYPRINTLANG(KOREAN)
	PRETTYPRINTLANG(KYRGYZ)
	PRETTYPRINTLANG(LATVIAN)
	PRETTYPRINTLANG(LITHUANIAN)
	PRETTYPRINTLANG(MACEDONIAN)
	PRETTYPRINTLANG(MALAY)
	PRETTYPRINTLANG(MALAYALAM)
	PRETTYPRINTLANG(MANIPURI)
	PRETTYPRINTLANG(MARATHI)
	PRETTYPRINTLANG(MONGOLIAN)
	PRETTYPRINTLANG(NEPALI)
	PRETTYPRINTLANG(NORWEGIAN)
	PRETTYPRINTLANG(ORIYA)
	PRETTYPRINTLANG(POLISH)
	PRETTYPRINTLANG(PORTUGUESE)
	PRETTYPRINTLANG(PUNJABI)
	PRETTYPRINTLANG(ROMANIAN)
	PRETTYPRINTLANG(RUSSIAN)
	PRETTYPRINTLANG(SANSKRIT)
	PRETTYPRINTLANG(SERBIAN)
	PRETTYPRINTLANG(SINDHI)
	PRETTYPRINTLANG(SLOVAK)
	PRETTYPRINTLANG(SLOVENIAN)
	PRETTYPRINTLANG(SPANISH)
	PRETTYPRINTLANG(SWAHILI)
	PRETTYPRINTLANG(SWEDISH)
	PRETTYPRINTLANG(SYRIAC)
	PRETTYPRINTLANG(TAMIL)
	PRETTYPRINTLANG(TATAR)
	PRETTYPRINTLANG(TELUGU)
	PRETTYPRINTLANG(THAI)
	PRETTYPRINTLANG(TURKISH)
	PRETTYPRINTLANG(UKRAINIAN)
	PRETTYPRINTLANG(URDU)
	PRETTYPRINTLANG(UZBEK)
	PRETTYPRINTLANG(VIETNAMESE)
	PRETTYPRINTLANG(GAELIC)
	PRETTYPRINTLANG(MALTESE)
	PRETTYPRINTLANG(MAORI)
	PRETTYPRINTLANG(RHAETO_ROMANCE)
	PRETTYPRINTLANG(SAAMI)
	PRETTYPRINTLANG(SORBIAN)
	PRETTYPRINTLANG(SUTU)
	PRETTYPRINTLANG(TSONGA)
	PRETTYPRINTLANG(TSWANA)
	PRETTYPRINTLANG(VENDA)
	PRETTYPRINTLANG(XHOSA)
	PRETTYPRINTLANG(ZULU)
	PRETTYPRINTLANG(ESPERANTO)
	PRETTYPRINTLANG(WALON)
	PRETTYPRINTLANG(CORNISH)
	PRETTYPRINTLANG(WELSH)
	PRETTYPRINTLANG(BRETON)
	return "Unknown language";
}
#endif

static int compare_accelerator(accelerator_t *accelerator1, accelerator_t *accelerator2) {
	int different = 0;
	event_t *ev1 = NULL, *ev2 = NULL;
	if(!different &&
	   ((accelerator1->memopt != accelerator2->memopt) ||
	   (accelerator1->lvc.version != accelerator2->lvc.version) ||
	   (accelerator1->lvc.characts != accelerator2->lvc.characts)))
		different = 1;
	ev1 = accelerator1->events;
	ev2 = accelerator2->events;
	while(!different && ev1 && ev2) {
		if(!different &&
		   ((ev1->id != ev2->id) ||
		   (ev1->flags != ev2->flags)))
			different = 1;
		ev1 = ev1->next;
		ev2 = ev2->next;
	}
	if(!different &&
	   ((ev1 && !ev2) || (!ev1 && ev2)))
		different = 1;
	return different;
}

static int compare_bitmap(bitmap_t *bitmap1, bitmap_t *bitmap2) {
	int different = 0;
	if(!different &&
	   ((bitmap1->memopt != bitmap2->memopt) ||
	   (bitmap1->data->lvc.version != bitmap2->data->lvc.version) ||
	   (bitmap1->data->lvc.characts != bitmap2->data->lvc.characts)))
		different = 1;
	return different;
}

static int compare_cursor(cursor_t *cursor1, cursor_t *cursor2) {
	int different = 0;
	if(!different &&
	   ((cursor1->id != cursor2->id) ||
	   (cursor1->width != cursor2->width) ||
	   (cursor1->height != cursor2->height) ||
	   (cursor1->xhot != cursor2->xhot) ||
	   (cursor1->yhot != cursor2->yhot)))
		different = 1;
	if(!different &&
	   ((cursor1->lvc.version != cursor2->lvc.version) ||
	   (cursor1->lvc.characts != cursor2->lvc.characts)))
		different = 1;
	return different;
}

static int compare_cursor_group(cursor_group_t *cursor_group1, cursor_group_t *cursor_group2) {
	int different = 0;
	cursor_t *cursor1 = NULL, *cursor2 = NULL;
	if(!different &&
	   ((cursor_group1->memopt != cursor_group2->memopt) ||
	   (cursor_group1->lvc.version != cursor_group2->lvc.version) ||
	   (cursor_group1->lvc.characts != cursor_group2->lvc.characts)))
		different = 1;
	if(!different &&
	   (cursor_group1->ncursor != cursor_group2->ncursor))
		different = 1;
	if(!different) {
		cursor1 = cursor_group1->cursorlist;
		cursor2 = cursor_group2->cursorlist;
		while(!different && cursor1 && cursor2) {
			different = compare_cursor(cursor1, cursor2);
			cursor1 = cursor1->next;
			cursor2 = cursor2->next;
		}
		if(!different &&
		   ((cursor1 && !cursor2) ||
		   (!cursor1 && cursor2)))
			different = 1;
	}
	return different;
}

static int compare_control(control_t *control1, control_t *control2) {
	int different = 0;
	char *nameid = NULL;
	int ignore_style;
	if(!different &&
		((control1 && !control2) ||
		(!control1 && control2)))
			different = 1;
	if(different || !control1 || !control2)
		return different;
	nameid = strdup(get_nameid_str(control1->ctlclass));
	if(!different && strcmp(nameid, get_nameid_str(control2->ctlclass)))
		different = 1;
	free(nameid);
        if (different)
            return different;

        /* allow the translators to set some styles */
        ignore_style = 0;
        if (control1->ctlclass->type == name_ord && control1->ctlclass->name.i_name == CT_BUTTON)
            ignore_style = 0x2000;          /* BS_MULTILINE*/

	if(!different && 
	   (control1->id != control2->id))
		different = 1;
	if(!different && control1->gotstyle && control2->gotstyle) {
		if((!control1->style || !control2->style) ||
		   (control1->style->and_mask || control2->style->and_mask) ||
		   ((control1->style->or_mask & ~ignore_style) != (control2->style->or_mask & ~ignore_style)))
			different = 1;
	} else if(!different &&
		  ((control1->gotstyle && !control2->gotstyle) ||
		  (!control1->gotstyle && control2->gotstyle)))
			different = 1;
	if(!different && control1->gotexstyle && control2->gotexstyle) {
		if((!control1->exstyle || !control2->exstyle) ||
		   (control1->exstyle->and_mask || control2->exstyle->and_mask) ||
		   (control1->exstyle->or_mask != control2->exstyle->or_mask))
			different = 1;
	} else if(!different &&
		  ((control1->gotexstyle && !control2->gotexstyle) ||
		  (!control1->gotexstyle && control2->gotexstyle)))
			different = 1;
	if(!different && control1->gothelpid && control2->gothelpid) {
		if(control1->helpid != control2->helpid)
			different = 1;
	} else if(!different &&
		  ((control1->gothelpid && !control2->gothelpid) ||
		  (!control1->gothelpid && control2->gothelpid)))
			different = 1;
	return different;
}

static int compare_dialog(dialog_t *dialog1, dialog_t *dialog2) {
	int different = 0;
	char *nameid = NULL;
	control_t *ctrl1, *ctrl2;
	if(!different &&
	   ((dialog1->memopt != dialog2->memopt) ||
	   (dialog1->lvc.version != dialog2->lvc.version) ||
	   (dialog1->lvc.characts != dialog2->lvc.characts)))
		different = 1;
	if(!different && dialog1->gotstyle && dialog2->gotstyle) {
		if((!dialog1->style || !dialog2->style) ||
		   (dialog1->style->and_mask || dialog2->style->and_mask) ||
		   (dialog1->style->or_mask != dialog2->style->or_mask))
			different = 1;
	} else if(!different &&
		  ((dialog1->gotstyle && !dialog2->gotstyle) ||
		  (!dialog1->gotstyle && dialog2->gotstyle)))
			different = 1;
	if(!different && dialog1->gotexstyle && dialog2->gotexstyle) {
		if((!dialog1->exstyle || !dialog2->exstyle) ||
		   (dialog1->exstyle->and_mask || dialog2->exstyle->and_mask) ||
		   (dialog1->exstyle->or_mask != dialog2->exstyle->or_mask))
			different = 1;
	} else if(!different &&
		  ((dialog1->gotexstyle && !dialog2->gotexstyle) ||
		  (!dialog1->gotexstyle && dialog2->gotexstyle)))
			different = 1;
	if(!different && dialog1->gothelpid && dialog2->gothelpid) {
		if(dialog1->helpid != dialog2->helpid)
			different = 1;
	} else if(!different &&
		  ((dialog1->gothelpid && !dialog2->gothelpid) ||
		  (!dialog1->gothelpid && dialog2->gothelpid)))
			different = 1;
	nameid = strdup(get_nameid_str(dialog1->menu));
	if(!different && strcmp(nameid, get_nameid_str(dialog2->menu)))
		different = 1;
	free(nameid);
	nameid = strdup(get_nameid_str(dialog1->dlgclass));
	if(!different && strcmp(nameid, get_nameid_str(dialog2->dlgclass)))
		different = 1;
	free(nameid);

        ctrl1 = dialog1->controls;
        ctrl2 = dialog2->controls;
        while(!different && (ctrl1 || ctrl2))
        {
            different = compare_control(ctrl1, ctrl2);
            if (ctrl1) ctrl1 = ctrl1->next;
            if (ctrl2) ctrl2 = ctrl2->next;
        }
	return different;
}

static int compare_font(font_t *font1, font_t *font2) {
	int different = 0;
	if(!different &&
	   ((font1->memopt != font2->memopt) ||
	   (font1->data->lvc.version != font2->data->lvc.version) ||
	   (font1->data->lvc.characts != font2->data->lvc.characts)))
		different = 1;
	return different;
}

static int compare_fontdir(fontdir_t *fontdir1, fontdir_t *fontdir2) {
	int different = 0;
	if(!different &&
	   ((fontdir1->memopt != fontdir2->memopt) ||
	   (fontdir1->data->lvc.version != fontdir2->data->lvc.version) ||
	   (fontdir1->data->lvc.characts != fontdir2->data->lvc.characts)))
		different = 1;
	return different;
}

static int compare_icon(icon_t *icon1, icon_t *icon2) {
	int different = 0;
	if(!different &&
	   ((icon1->id != icon2->id) ||
	   (icon1->width != icon2->width) ||
	   (icon1->height != icon2->height)))
		different = 1;
	if(!different &&
	   ((icon1->lvc.version != icon2->lvc.version) ||
	   (icon1->lvc.characts != icon2->lvc.characts)))
		different = 1;
	return different;
}

static int compare_icon_group(icon_group_t *icon_group1, icon_group_t *icon_group2) {
	int different = 0;
	icon_t *icon1 = NULL, *icon2 = NULL;
	if(!different &&
	   ((icon_group1->memopt != icon_group2->memopt) ||
	   (icon_group1->lvc.version != icon_group2->lvc.version) ||
	   (icon_group1->lvc.characts != icon_group2->lvc.characts)))
		different = 1;
	if(!different &&
	   (icon_group1->nicon != icon_group2->nicon))
		different = 1;
	if(!different) {
		icon1 = icon_group1->iconlist;
		icon2 = icon_group2->iconlist;
		while(!different && icon1 && icon2) {
			different = compare_icon(icon1, icon2);
			icon1 = icon1->next;
			icon2 = icon2->next;
		}
		if(!different &&
		   ((icon1 && !icon2) ||
		   (!icon1 && icon2)))
			different = 1;
	}
	return different;
}

static int compare_menu_item(menu_item_t *menu_item1, menu_item_t *menu_item2) {
	int different = 0;
	while(!different && menu_item1 && menu_item2) {
		if(menu_item1->popup && menu_item2->popup) {
			if(!different && menu_item1->gotid && menu_item2->gotid) {
				if(menu_item1->id != menu_item2->id)
					different = 1;
			} else if(!different &&
				  ((menu_item1->gotid && !menu_item2->gotid) ||
				  (!menu_item1->gotid && menu_item2->gotid)))
					different = 1;
			if(!different && menu_item1->gottype && menu_item2->gottype) {
				if(menu_item1->type != menu_item2->type)
					different = 1;
			} else if(!different &&
				  ((menu_item1->gottype && !menu_item2->gottype) ||
				  (!menu_item1->gottype && menu_item2->gottype)))
					different = 1;
			if(!different && menu_item1->gotstate && menu_item2->gotstate) {
				if(menu_item1->state != menu_item2->state)
					different = 1;
			} else if(!different &&
				  ((menu_item1->gotstate && !menu_item2->gotstate) ||
				  (!menu_item1->gotstate && menu_item2->gotstate)))
					different = 1;
			if(!different && menu_item1->gothelpid && menu_item2->gothelpid) {
				if(menu_item1->helpid != menu_item2->helpid)
					different = 1;
			} else if(!different &&
				  ((menu_item1->gothelpid && !menu_item2->gothelpid) ||
				  (!menu_item1->gothelpid && menu_item2->gothelpid)))
					different = 1;
			if(!different)
				different = compare_menu_item(menu_item1->popup, menu_item2->popup);
		} else if(!menu_item1->popup && !menu_item2->popup) {
			if(menu_item1->name && menu_item2->name) {
				if(!different && menu_item1->gotid && menu_item2->gotid) {
					if(menu_item1->id != menu_item2->id)
						different = 1;
				} else if(!different &&
					  ((menu_item1->gotid && !menu_item2->gotid) ||
					  (!menu_item1->gotid && menu_item2->gotid)))
						different = 1;
				if(!different && menu_item1->gottype && menu_item2->gottype) {
					if(menu_item1->type != menu_item2->type)
						different = 1;
				} else if(!different &&
					  ((menu_item1->gottype && !menu_item2->gottype) ||
					  (!menu_item1->gottype && menu_item2->gottype)))
						different = 1;
				if(!different && menu_item1->gotstate && menu_item2->gotstate) {
					if(menu_item1->state != menu_item2->state)
						different = 1;
				} else if(!different &&
					  ((menu_item1->gotstate && !menu_item2->gotstate) ||
					  (!menu_item1->gotstate && menu_item2->gotstate)))
						different = 1;
				if(!different && menu_item1->gothelpid && menu_item2->gothelpid) {
					if(menu_item1->helpid != menu_item2->helpid)
						different = 1;
				} else if(!different &&
					  ((menu_item1->gothelpid && !menu_item2->gothelpid) ||
					  (!menu_item1->gothelpid && menu_item2->gothelpid)))
						different = 1;
			} else if((menu_item1->name && !menu_item2->name) ||
				  (!menu_item1->name && menu_item2->name))
					different = 1;
		} else
			different = 1;
		menu_item1 = menu_item1->next;
		menu_item2 = menu_item2->next;
	}
	if(!different &&
	   ((menu_item1 && !menu_item2) ||
	   (!menu_item1 && menu_item2)))
		different = 1;
	return different;
}

static int compare_menu(menu_t *menu1, menu_t *menu2) {
	int different = 0;
	if(!different &&
	   ((menu1->memopt != menu2->memopt) ||
	   (menu1->lvc.version != menu2->lvc.version) ||
	   (menu1->lvc.characts != menu2->lvc.characts)))
		different = 1;
	if(!different)
		different = compare_menu_item(menu1->items, menu2->items);
	return different;
}

static int compare_rcdata(rcdata_t *rcdata1, rcdata_t *rcdata2) {
	int different = 0;
	if(!different &&
	   ((rcdata1->memopt != rcdata2->memopt) ||
	   (rcdata1->data->lvc.version != rcdata2->data->lvc.version) ||
	   (rcdata1->data->lvc.characts != rcdata2->data->lvc.characts)))
		different = 1;
	return different;
}

static int compare_html(html_t *rcdata1, html_t *rcdata2) {
        int different = 0;
        if(!different &&
           ((rcdata1->memopt != rcdata2->memopt) ||
           (rcdata1->data->lvc.version != rcdata2->data->lvc.version) ||
           (rcdata1->data->lvc.characts != rcdata2->data->lvc.characts)))
                different = 1;
        return different;
}

static int compare_stringtable(stringtable_t *stringtable1, stringtable_t *stringtable2) {
	int different = 0;
	int i;
	while(!different && stringtable1 && stringtable2) {
		if((stringtable1->memopt != stringtable2->memopt) ||
		   (stringtable1->lvc.version != stringtable2->lvc.version) ||
		   (stringtable1->lvc.characts != stringtable2->lvc.characts))
			different = 1;
		if(!different) {
			if((stringtable1->nentries != stringtable2->nentries) ||
			   (stringtable1->idbase != stringtable2->idbase))
				different = 1;
			else
				for(i = 0 ; i < stringtable1->nentries; i++)
					if((stringtable1->entries[i].id != stringtable2->entries[i].id) ||
					   (stringtable1->entries[i].memopt != stringtable2->entries[i].memopt) ||
					   (stringtable1->entries[i].str && !stringtable2->entries[i].str) ||
					   (!stringtable1->entries[i].str && stringtable2->entries[i].str)) {
						different = 1;
						break;
					}
		}
		stringtable1 = stringtable1->next;
		stringtable2 = stringtable2->next;
	}
	return different;
}

static int compare_user(user_t *user1, user_t *user2) {
	int different = 0;
	char *nameid = NULL;
	if(!different &&
	   ((user1->memopt != user2->memopt) ||
	   (user1->data->lvc.version != user2->data->lvc.version) ||
	   (user1->data->lvc.characts != user2->data->lvc.characts)))
		different = 1;
	nameid = strdup(get_nameid_str(user1->type));
	if(!different && strcmp(nameid, get_nameid_str(user2->type)))
		different = 1;
	free(nameid);
	return different;
}

static int compare_messagetable(messagetable_t *messagetable1, messagetable_t *messagetable2) {
	int different = 0;
	if(!different &&
	   ((messagetable1->memopt != messagetable2->memopt) ||
	   (messagetable1->data->lvc.version != messagetable2->data->lvc.version) ||
	   (messagetable1->data->lvc.characts != messagetable2->data->lvc.characts)))
		different = 1;
	return different;
}

static int compare_string(string_t *string1, string_t *string2) {
	int different = 0;
	if(!different &&
	   ((string1->size != string2->size) ||
	   (string1->type != string2->type)))
		different = 1;
	if(!different) {
		if(string1->type == str_char)
			different = memcmp(string1->str.cstr, string2->str.cstr, string1->size);
		else if(string1->type == str_unicode)
			different = memcmp(string1->str.wstr, string2->str.wstr, string1->size*sizeof(WCHAR));
		else
			different = 1;
	}
	return different;
}

static int compare_ver_block(ver_block_t *ver_block1, ver_block_t *ver_block2);

static int compare_ver_value(ver_value_t *ver_value1, ver_value_t *ver_value2) {
	int different = 0;
	int i = 0;
	if(!different &&
	   (ver_value1->type == ver_value2->type)) {
		switch(ver_value1->type) {
			case val_str:
				if(!different && ver_value1->key && ver_value2->key)
					different = compare_string(ver_value1->key, ver_value2->key);
				else if(!different &&
					((ver_value1->key && !ver_value2->key) ||
					(!ver_value1->key && ver_value2->key)))
						different = 1;
				break;
			case val_words:
				if(!different && ver_value1->key && ver_value2->key)
					different = compare_string(ver_value1->key, ver_value2->key);
				else if(!different &&
					((ver_value1->key && !ver_value2->key) ||
					(!ver_value1->key && ver_value2->key)))
						different = 1;
				if(!different && ver_value1->value.words && ver_value2->value.words) {
					if(!different &&
					   (ver_value1->value.words->nwords != ver_value2->value.words->nwords))
						different = 1;
					if(!different)
						for(i = 0; i < ver_value1->value.words->nwords; i++) {
							if(ver_value1->value.words->words[i] != ver_value2->value.words->words[i]) {
								different = 1;
								break;
							}
						}
				} else if(!different &&
					  ((ver_value1->value.words && !ver_value2->value.words) ||
					  (!ver_value1->value.words && ver_value2->value.words)))
						different = 1;
				break;
			case val_block:
				if(!different && ver_value1->value.block && ver_value2->value.block)
					different = compare_ver_block(ver_value1->value.block, ver_value2->value.block);
				else if(!different &&
					((ver_value1->value.block && !ver_value2->value.block) ||
					(!ver_value1->value.block && ver_value2->value.block)))
						different = 1;
				break;
			default:
				different = 1;
		}
	} else
		different = 1;
	return different;
}

static int compare_ver_block(ver_block_t *ver_block1, ver_block_t *ver_block2) {
	int different = 0;
	ver_value_t *ver_value1 = NULL, *ver_value2 = NULL;
	if(!different) {
		ver_value1 = ver_block1->values;
		ver_value2 = ver_block2->values;
		while(!different && ver_value1 && ver_value2) {
			different = compare_ver_value(ver_value1, ver_value2);
			ver_value1 = ver_value1->next;
			ver_value2 = ver_value2->next;
		}
		if(!different &&
		   ((ver_value1 && !ver_value2) ||
		   (!ver_value1 && ver_value2)))
			different = 1;
	}
	return different;
}

static int compare_versioninfo(versioninfo_t *versioninfo1, versioninfo_t *versioninfo2) {
	int different = 0;
	ver_block_t *ver_block1 = NULL, *ver_block2 = NULL;
	if(!different &&
	   ((versioninfo1->memopt != versioninfo2->memopt) ||
	   (versioninfo1->lvc.version != versioninfo2->lvc.version) ||
	   (versioninfo1->lvc.characts != versioninfo2->lvc.characts)))
		different = 1;
	if(!different && versioninfo1->gotit.fv && versioninfo2->gotit.fv) {
		if((versioninfo1->filever_maj1 != versioninfo2->filever_maj1) ||
		   (versioninfo1->filever_maj2 != versioninfo2->filever_maj2) ||
		   (versioninfo1->filever_min1 != versioninfo2->filever_min1) ||
		   (versioninfo1->filever_min2 != versioninfo2->filever_min2))
			different = 1;
	} else if(!different &&
		  ((versioninfo1->gotit.fv && !versioninfo2->gotit.fv) ||
		  (!versioninfo1->gotit.fv && versioninfo2->gotit.fv)))
			different = 1;
	if(!different && versioninfo1->gotit.pv && versioninfo2->gotit.pv) {
		if((versioninfo1->prodver_maj1 != versioninfo2->prodver_maj1) ||
		   (versioninfo1->prodver_maj2 != versioninfo2->prodver_maj2) ||
		   (versioninfo1->prodver_min1 != versioninfo2->prodver_min1) ||
		   (versioninfo1->prodver_min2 != versioninfo2->prodver_min2))
			different = 1;
	} else if(!different &&
		  ((versioninfo1->gotit.pv && !versioninfo2->gotit.pv) ||
		  (!versioninfo1->gotit.pv && versioninfo2->gotit.pv)))
			different = 1;
	if(!different && versioninfo1->gotit.fo && versioninfo2->gotit.fo) {
		if(versioninfo1->fileos != versioninfo2->fileos)
			different = 1;
	} else if(!different &&
		  ((versioninfo1->gotit.fo && !versioninfo2->gotit.fo) ||
		  (!versioninfo1->gotit.fo && versioninfo2->gotit.fo)))
			different = 1;
	if(!different && versioninfo1->gotit.ff && versioninfo2->gotit.ff) {
		if(versioninfo1->fileflags != versioninfo2->fileflags)
			different = 1;
	} else if(!different &&
		  ((versioninfo1->gotit.ff && !versioninfo2->gotit.ff) ||
		  (!versioninfo1->gotit.ff && versioninfo2->gotit.ff)))
			different = 1;
	if(!different && versioninfo1->gotit.ffm && versioninfo2->gotit.ffm) {
		if(versioninfo1->fileflagsmask != versioninfo2->fileflagsmask)
			different = 1;
	} else if(!different &&
		  ((versioninfo1->gotit.ffm && !versioninfo2->gotit.ffm) ||
		  (!versioninfo1->gotit.ffm && versioninfo2->gotit.ffm)))
			different = 1;
	if(!different && versioninfo1->gotit.ft && versioninfo2->gotit.ft) {
		if(versioninfo1->filetype != versioninfo2->filetype)
			different = 1;
	} else if(!different &&
		  ((versioninfo1->gotit.ft && !versioninfo2->gotit.ft) ||
		  (!versioninfo1->gotit.ft && versioninfo2->gotit.ft)))
			different = 1;
	if(!different && versioninfo1->gotit.fst && versioninfo2->gotit.fst) {
		if(versioninfo1->filesubtype != versioninfo2->filesubtype)
			different = 1;
	} else if(!different &&
		  ((versioninfo1->gotit.fst && !versioninfo2->gotit.fst) ||
		  (!versioninfo1->gotit.fst && versioninfo2->gotit.fst)))
			different = 1;
	if(!different) {
		ver_block1 = versioninfo1->blocks;
		ver_block2 = versioninfo2->blocks;
		while(!different && ver_block1 && ver_block2) {
			different = compare_ver_block(ver_block1, ver_block2);
			ver_block1 = ver_block1->next;
			ver_block2 = ver_block2->next;
		}
		if(!different &&
		   ((ver_block1 && !ver_block2) ||
		   (!ver_block1 && ver_block2)))
			different = 1;
	}
	return different;
}

static int compare_dlginit(dlginit_t *dlginit1, dlginit_t *dlginit2) {
	int different = 0;
	if(!different &&
	   ((dlginit1->memopt != dlginit2->memopt) ||
	   (dlginit1->data->lvc.version != dlginit2->data->lvc.version) ||
	   (dlginit1->data->lvc.characts != dlginit2->data->lvc.characts)))
		different = 1;
	return different;
}

static int compare_toolbar_item(toolbar_item_t *toolbar_item1, toolbar_item_t *toolbar_item2) {
	int different = 0;
	while(!different && toolbar_item1 && toolbar_item2) {
		if((toolbar_item1->id && !toolbar_item2->id) ||
		   (!toolbar_item1->id && toolbar_item2->id))
			different = 1;
		toolbar_item1 = toolbar_item1->next;
		toolbar_item2 = toolbar_item2->next;
	}
	if(!different &&
	   ((toolbar_item1 && !toolbar_item2) ||
	   (!toolbar_item1 && toolbar_item2)))
		different = 1;
	return different;
}

static int compare_toolbar(toolbar_t *toolbar1, toolbar_t *toolbar2) {
	int different = 0;
	if(!different &&
	   ((toolbar1->memopt != toolbar2->memopt) ||
	   (toolbar1->lvc.version != toolbar2->lvc.version) ||
	   (toolbar1->lvc.characts != toolbar2->lvc.characts)))
		different = 1;
	if(!different)
		different = compare_toolbar_item(toolbar1->items, toolbar2->items);
	return different;
}

static int compare_ani_curico(ani_curico_t *ani_curico1, ani_curico_t *ani_curico2) {
	int different = 0;
	if(!different &&
	   ((ani_curico1->memopt != ani_curico2->memopt) ||
	   (ani_curico1->data->lvc.version != ani_curico2->data->lvc.version) ||
	   (ani_curico1->data->lvc.characts != ani_curico2->data->lvc.characts)))
		different = 1;
	return different;
}

static int compare(resource_t *resource1, resource_t *resource2) {
	switch(resource1->type) {
		case res_acc:
			return compare_accelerator(resource1->res.acc, resource2->res.acc);
		case res_bmp:
			return compare_bitmap(resource1->res.bmp, resource2->res.bmp);
		case res_cur:
			return compare_cursor(resource1->res.cur, resource2->res.cur);
		case res_curg:
			return compare_cursor_group(resource1->res.curg, resource2->res.curg);
		case res_dlg:
			return compare_dialog(resource1->res.dlg, resource2->res.dlg);
		case res_fnt:
			return compare_font(resource1->res.fnt, resource2->res.fnt);
		case res_fntdir:
			return compare_fontdir(resource1->res.fnd, resource2->res.fnd);
		case res_ico:
			return compare_icon(resource1->res.ico, resource2->res.ico);
		case res_icog:
			return compare_icon_group(resource1->res.icog, resource2->res.icog);
		case res_men:
			return compare_menu(resource1->res.men, resource2->res.men);
		case res_rdt:
			return compare_rcdata(resource1->res.rdt, resource2->res.rdt);
		case res_stt:
			return compare_stringtable(resource1->res.stt, resource2->res.stt);
		case res_usr:
			return compare_user(resource1->res.usr, resource2->res.usr);
		case res_html:
		        return compare_html(resource1->res.html, resource2->res.html);
		case res_msg:
			return compare_messagetable(resource1->res.msg, resource2->res.msg);
		case res_ver:
			return compare_versioninfo(resource1->res.ver, resource2->res.ver);
		case res_dlginit:
			return compare_dlginit(resource1->res.dlgi, resource2->res.dlgi);
		case res_toolbar:
			return compare_toolbar(resource1->res.tbt, resource2->res.tbt);
		case res_anicur:
		case res_aniico:
			return compare_ani_curico(resource1->res.ani, resource2->res.ani);
		default:
			/* Not supposed to reach here */
			fprintf(stderr, "Not supposed to reach here (compare())\n");
			abort();
			return -1;
	}
}

typedef struct resource_lang_node
{
    language_t lang;
    resource_t *res;
    struct resource_lang_node *next;
} resource_lang_node_t;

typedef struct resource_id_node
{
    name_id_t *id;
    resource_lang_node_t *langs;
    struct resource_id_node *next;
} resource_id_node_t;

struct
{
    int enabled;
    struct resource_id_node *ids;
} verify_tab[res_usr+1];

static void add_resource(resource_t *res)
{
    resource_id_node_t *idnode;
    resource_lang_node_t *langnode;
    if (!verify_tab[res->type].enabled)
    {
	fprintf(stderr, "ERR: Report this: unknown resource type parsed %08x\n", res->type);
	return;
    }

    for (idnode = verify_tab[res->type].ids; idnode; idnode = idnode->next)
        if (compare_name_id(idnode->id, res->name) == 0)
            break;

    if (idnode == NULL)
    {
        idnode = xmalloc(sizeof(resource_id_node_t));
        idnode->id = res->name;
        idnode->langs = NULL;
        idnode->next = verify_tab[res->type].ids;
        verify_tab[res->type].ids = idnode;
    }

    for (langnode = idnode->langs; langnode; langnode = langnode->next)
        if (compare_lang(langnode->lang, get_language(res)) == 0)
        {
            fprintf(stderr, "ERR: resource %s [type %x] language %03x:%02x duplicated!\n",
                get_nameid_str(res->name), res->type, langnode->lang.id, langnode->lang.sub);
            return;
        }

    langnode = xmalloc(sizeof(resource_lang_node_t));
    langnode->res = res;
    langnode->lang = get_language(res);
    langnode->next = idnode->langs;
    idnode->langs = langnode;
}

static void setup_tabs(void)
{
    int i;

    for (i = 0; i <= res_usr; i++)
	switch(i) {
		case res_acc:
		case res_bmp:
		case res_cur:
		case res_curg:
		case res_dlg:
		case res_fnt:
		case res_fntdir:
		case res_ico:
		case res_icog:
		case res_men:
		case res_rdt:
		case res_stt:
		case res_usr:
		case res_msg:
		case res_ver:
		case res_dlginit:
		case res_toolbar:
		case res_anicur:
	        case res_aniico:
		case res_html:
		    verify_tab[i].enabled = 1;
		    break;
	}
}

static const char *get_typename_for_int(int type) {
    resource_t res;
    res.type = type;
    return get_typename(&res);
}

static resource_t *find_main(int type, name_id_t *id, resource_lang_node_t *langnode)
{
    resource_t *neutral = NULL, *en = NULL, *en_US = NULL;
    for (; langnode; langnode = langnode->next)
    {
        if (langnode->lang.id == LANG_NEUTRAL && langnode->lang.sub == SUBLANG_NEUTRAL)
            neutral = langnode->res;
        if (langnode->lang.id == MASTER_LANGUAGE && langnode->lang.sub == SUBLANG_NEUTRAL)
            en = langnode->res;
        if (langnode->lang.id == MASTER_LANGUAGE && langnode->lang.sub == MASTER_SUBLANGUAGE)
            en_US = langnode->res;
    }

    if (neutral != NULL && (en != NULL || en_US != NULL))
    {
        fprintf(stderr, "INFO: Resource %04x/%s has both NEUTRAL and MASTER language translarion\n",
            type, get_nameid_str(id));
    }

    if (en_US != NULL) return en_US;
    if (en != NULL) return en;
    return neutral;
}

void verify_translations(resource_t *top) {
    resource_t *curr = top;
    resource_id_node_t *idnode;
    resource_lang_node_t *langnode;
    int type;

    setup_tabs();
    while (curr)
    {
        add_resource(curr);
        curr = curr->next;
    }

    for (type = 0; type <= res_usr; type++)
    {
        printf("TYPE NEXT [%s]\n", get_typename_for_int(type));
        for (idnode = verify_tab[type].ids; idnode; idnode = idnode->next)
        {
            resource_t *mainres;
            printf("RESOURCE [%s]\n", get_nameid_str(idnode->id));

            mainres = find_main(type, idnode->id, idnode->langs);
            if (!mainres)
            {
                fprintf(stderr, "ERR: resource %04x/%s has translation(s) but not available in NEUTRAL or MASTER language\n",
                    type, get_nameid_str(idnode->id));
                for (langnode = idnode->langs; langnode; langnode = langnode->next)
                    printf("EXTRA %03x:%02x\n", langnode->lang.id, langnode->lang.sub);
                continue;
            }

            if (get_language_id(mainres) == LANG_NEUTRAL && idnode->langs->next == NULL) {
                printf("NOTRANSL\n");
                continue;
            }

            for (langnode = idnode->langs; langnode; langnode = langnode->next)
            {
                printf("EXIST %03x:%02x\n", langnode->lang.id, langnode->lang.sub);
                if (compare(langnode->res, mainres))
                {
                    printf("DIFF %03x:%02x\n", langnode->lang.id, langnode->lang.sub);
                }
            }
        }
    }
}
