/*
 * 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_dlgex:
			return *resource->res.dlgex->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_menex:
			return *resource->res.menex->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;
	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_dialogex(dialogex_t *dialogex1, dialogex_t *dialogex2) {
	int different = 0;
	char *nameid = NULL;
	control_t *ctrl1, *ctrl2;
	if(!different &&
	   ((dialogex1->memopt != dialogex2->memopt) ||
	   (dialogex1->lvc.version != dialogex2->lvc.version) ||
	   (dialogex1->lvc.characts != dialogex2->lvc.characts)))
		different = 1;
	if(!different && dialogex1->gotstyle && dialogex2->gotstyle) {
		if((!dialogex1->style || !dialogex2->style) ||
		   (dialogex1->style->and_mask || dialogex2->style->and_mask) ||
		   (dialogex1->style->or_mask != dialogex2->style->or_mask))
			different = 1;
	} else if(!different &&
		  ((dialogex1->gotstyle && !dialogex2->gotstyle) ||
		  (!dialogex1->gotstyle && dialogex2->gotstyle)))
			different = 1;
	if(!different && dialogex1->gotexstyle && dialogex2->gotexstyle) {
		if((!dialogex1->exstyle || !dialogex2->exstyle) ||
		   (dialogex1->exstyle->and_mask || dialogex2->exstyle->and_mask) ||
		   (dialogex1->exstyle->or_mask != dialogex2->exstyle->or_mask))
			different = 1;
	} else if(!different &&
		  ((dialogex1->gotexstyle && !dialogex2->gotexstyle) ||
		  (!dialogex1->gotexstyle && dialogex2->gotexstyle)))
			different = 1;
	if(!different && dialogex1->gothelpid && dialogex2->gothelpid) {
		if(dialogex1->helpid != dialogex2->helpid)
			different = 1;
	} else if(!different &&
		  ((dialogex1->gothelpid && !dialogex2->gothelpid) ||
		  (!dialogex1->gothelpid && dialogex2->gothelpid)))
			different = 1;
	nameid = strdup(get_nameid_str(dialogex1->menu));
	if(!different && strcmp(nameid, get_nameid_str(dialogex2->menu)))
		different = 1;
	free(nameid);
	nameid = strdup(get_nameid_str(dialogex1->dlgclass));
	if(!different && strcmp(nameid, get_nameid_str(dialogex2->dlgclass)))
		different = 1;
	free(nameid);

        ctrl1 = dialogex1->controls;
        ctrl2 = dialogex2->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)
			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((menu_item1->id != menu_item2->id) ||
				   (menu_item1->state != menu_item2->state))
					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_menuex_item(menuex_item_t *menuex_item1, menuex_item_t *menuex_item2) {
	int different = 0;
	while(!different && menuex_item1 && menuex_item2) {
		if(menuex_item1->popup && menuex_item2->popup) {
			if(!different && menuex_item1->gotid && menuex_item2->gotid) {
				if(menuex_item1->id != menuex_item2->id)
					different = 1;
			} else if(!different &&
				  ((menuex_item1->gotid && !menuex_item2->gotid) ||
				  (!menuex_item1->gotid && menuex_item2->gotid)))
					different = 1;
			if(!different && menuex_item1->gottype && menuex_item2->gottype) {
				if(menuex_item1->type != menuex_item2->type)
					different = 1;
			} else if(!different &&
				  ((menuex_item1->gottype && !menuex_item2->gottype) ||
				  (!menuex_item1->gottype && menuex_item2->gottype)))
					different = 1;
			if(!different && menuex_item1->gotstate && menuex_item2->gotstate) {
				if(menuex_item1->state != menuex_item2->state)
					different = 1;
			} else if(!different &&
				  ((menuex_item1->gotstate && !menuex_item2->gotstate) ||
				  (!menuex_item1->gotstate && menuex_item2->gotstate)))
					different = 1;
			if(!different && menuex_item1->gothelpid && menuex_item2->gothelpid) {
				if(menuex_item1->helpid != menuex_item2->helpid)
					different = 1;
			} else if(!different &&
				  ((menuex_item1->gothelpid && !menuex_item2->gothelpid) ||
				  (!menuex_item1->gothelpid && menuex_item2->gothelpid)))
					different = 1;
			if(!different)
				different = compare_menuex_item(menuex_item1->popup, menuex_item2->popup);
		} else if(!menuex_item1->popup && !menuex_item2->popup) {
			if(menuex_item1->name && menuex_item2->name) {
				if(!different && menuex_item1->gotid && menuex_item2->gotid) {
					if(menuex_item1->id != menuex_item2->id)
						different = 1;
				} else if(!different &&
					  ((menuex_item1->gotid && !menuex_item2->gotid) ||
					  (!menuex_item1->gotid && menuex_item2->gotid)))
						different = 1;
				if(!different && menuex_item1->gottype && menuex_item2->gottype) {
					if(menuex_item1->type != menuex_item2->type)
						different = 1;
				} else if(!different &&
					  ((menuex_item1->gottype && !menuex_item2->gottype) ||
					  (!menuex_item1->gottype && menuex_item2->gottype)))
						different = 1;
				if(!different && menuex_item1->gotstate && menuex_item2->gotstate) {
					if(menuex_item1->state != menuex_item2->state)
						different = 1;
				} else if(!different &&
					  ((menuex_item1->gotstate && !menuex_item2->gotstate) ||
					  (!menuex_item1->gotstate && menuex_item2->gotstate)))
						different = 1;
				if(!different && menuex_item1->gothelpid && menuex_item2->gothelpid) {
					if(menuex_item1->helpid != menuex_item2->helpid)
						different = 1;
				} else if(!different &&
					  ((menuex_item1->gothelpid && !menuex_item2->gothelpid) ||
					  (!menuex_item1->gothelpid && menuex_item2->gothelpid)))
						different = 1;
			} else if((menuex_item1->name && !menuex_item2->name) ||
				  (!menuex_item1->name && menuex_item2->name))
					different = 1;
		} else
			different = 1;
		menuex_item1 = menuex_item1->next;
		menuex_item2 = menuex_item2->next;
	}
	if(!different &&
	   ((menuex_item1 && !menuex_item2) ||
	   (!menuex_item1 && menuex_item2)))
		different = 1;
	return different;
}

static int compare_menuex(menuex_t *menuex1, menuex_t *menuex2) {
	int different = 0;
	if(!different &&
	   ((menuex1->memopt != menuex2->memopt) ||
	   (menuex1->lvc.version != menuex2->lvc.version) ||
	   (menuex1->lvc.characts != menuex2->lvc.characts)))
		different = 1;
	if(!different)
		different = compare_menuex_item(menuex1->items, menuex2->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_dlgex:
			return compare_dialogex(resource1->res.dlgex, resource2->res.dlgex);
		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_menex:
			return compare_menuex(resource1->res.menex, resource2->res.menex);
		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_dlgex:
		case res_fnt:
		case res_fntdir:
		case res_ico:
		case res_icog:
		case res_men:
		case res_menex:
		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);
                }
            }
        }
    }
}
