# The MIT License (MIT)
#
# Copyright (C) 2026 Scott Duensing
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.

# DVX Widget Modules Makefile for DJGPP cross-compilation
#
# Each widget lives in its own subdirectory with its .c, .res, and .bmp.
# Each .wgt is a DXE loaded by the loader at startup.

include ../../common.mk

CFLAGS        = $(DOS_CFLAGS) -I../../libs/kpunch/libdvx -I../../libs/kpunch/libdvx/platform -I../../libs/kpunch/libtasks -I../../libs/kpunch/libdvx/thirdparty
DVXRES        = ../../../bin/host/dvxres

OBJDIR = ../../../obj/widgets
WGTDIR = ../../../bin/widgets/kpunch

# Widget name -> directory, source, short name for .wgt/.res
# Format: wgtShortName:dirName:srcFile:resFile
WIDGETS = \
	box:box:widgetBox:box \
	button:button:widgetButton:button \
	canvas:canvas:widgetCanvas:canvas \
	checkbox:checkbox:widgetCheckbox:checkbox \
	combobox:comboBox:widgetComboBox:combobox \
	dropdown:dropdown:widgetDropdown:dropdown \
	imgbtn:imageButton:widgetImageButton:imgbtn \
	image:image:widgetImage:image \
	helpview:helpView:widgetHelpView:helpview \
	label:label:widgetLabel:label \
	listbox:listBox:widgetListBox:listbox \
	listview:listView:widgetListView:listview \
	progress:progressBar:widgetProgressBar:progress \
	radio:radio:widgetRadio:radio \
	richedit:richEdit:widgetRichEdit:richedit \
	richlbl:richLabel:widgetRichLabel:richlbl \
	scrlpane:scrollPane:widgetScrollPane:scrlpane \
	separatr:separator:widgetSeparator:separatr \
	slider:slider:widgetSlider:slider \
	spacer:spacer:widgetSpacer:spacer \
	spinner:spinner:widgetSpinner:spinner \
	splitter:splitter:widgetSplitter:splitter \
	statbar:statusBar:widgetStatusBar:statbar \
	tabctrl:tabControl:widgetTabControl:tabctrl \
	ansiterm:ansiTerm:widgetAnsiTerm:terminal \
	textinpt:textInput:widgetTextInput:textinpt \
	timer:timer:widgetTimer:timer \
	datactrl:dataCtrl:widgetDataCtrl:datactr \
	dbgrid:dbGrid:widgetDbGrid:dbgrid \
	toolbar:toolbar:widgetToolbar:toolbar \
	treeview:treeView:widgetTreeView:treeview \
	wrapbox:wrapBox:widgetWrapBox:wrapbox

# Fields of a WIDGETS entry
wshort = $(word 1,$(subst :, ,$1))
wdir   = $(word 2,$(subst :, ,$1))
wsrc   = $(word 3,$(subst :, ,$1))
wres   = $(word 4,$(subst :, ,$1))

# Extract lists
WGT_NAMES = $(foreach w,$(WIDGETS),$(call wshort,$w))
WGT_MODS  = $(foreach n,$(WGT_NAMES),$(WGTDIR)/$(n)/$(n).wgt)
OBJS      = $(foreach w,$(WIDGETS),$(OBJDIR)/$(call wsrc,$w).o)

# Module dependency lists: a widget ships <srcDir>/<shortName>.dep when
# it needs other modules loaded first.
WGT_DEPS  = $(foreach w,$(WIDGETS),$(if $(wildcard $(call wdir,$w)/$(call wshort,$w).dep),$(WGTDIR)/$(call wshort,$w)/$(call wshort,$w).dep))

# Help sources: every widget directory must carry its .dhs (system help)
# and may carry a .bhs (BASIC help); both are deployed next to the .wgt.
WGT_HELP_MISSING = $(foreach w,$(WIDGETS),$(if $(wildcard $(call wdir,$w)/*.dhs),,$(call wdir,$w)))

# Native host build (test harness): every widget becomes a plain ELF
# shared object with wgtRegister exported unprefixed; the test binary
# dlopens them RTLD_GLOBAL.  Undefined references to other DVX libraries
# (texthelp, listhelp, sql) resolve at load time from the host executable.
# SAN/COV per common.mk and must match the executable's setting.
HOSTOBJDIR    = $(HOST_OBJROOT)/widgets
HOSTCFLAGS    = $(HOST_CFLAGS) -I../../libs/kpunch/libdvx -I../../libs/kpunch/libdvx/platform -I../../libs/kpunch/libtasks -I../../libs/kpunch/libdvx/thirdparty
HOSTLDFLAGS   = -shared $(HOST_LDFLAGS)
HOST_SOS      = $(foreach n,$(WGT_NAMES),$(HOSTOBJDIR)/$(n).so)

.PHONY: all clean host host-clean deploy-helpsrc

all: $(WGT_MODS) $(WGT_DEPS)

host: $(HOST_SOS)

define HOST_WIDGET_RULE
$(HOSTOBJDIR)/$(call wshort,$1).so: $(call wdir,$1)/$(call wsrc,$1).c $$(DVX_MAKEFILES)
	@mkdir -p $(HOSTOBJDIR)
	$$(HOSTCC) $$(HOSTCFLAGS) $$(HOSTLDFLAGS) -o $$@ $$<
endef

$(foreach w,$(WIDGETS),$(eval $(call HOST_WIDGET_RULE,$w)))

host-clean:
	rm -rf $(HOSTOBJDIR)

define WIDGET_RULES
$(OBJDIR)/$(call wsrc,$1).o: $(call wdir,$1)/$(call wsrc,$1).c $$(DVX_MAKEFILES) | $(OBJDIR)
	$$(CC) $$(CFLAGS) -c -o $$@ $$<

$(WGTDIR)/$(call wshort,$1)/$(call wshort,$1).wgt: $(OBJDIR)/$(call wsrc,$1).o $$(wildcard $(call wdir,$1)/$(call wres,$1).res) $$(wildcard $(call wdir,$1)/*.bmp) | $(WGTDIR)/$(call wshort,$1)
	$$(DXE3GEN) -o $(WGTDIR)/$(call wshort,$1)/$(call wshort,$1).dxe -U $$<
	mv $(WGTDIR)/$(call wshort,$1)/$(call wshort,$1).dxe $$@
	@if [ -f $(call wdir,$1)/$(call wres,$1).res ]; then \
		cd $(call wdir,$1) && ../$(DVXRES) build ../$$@ $(call wres,$1).res; \
	fi

$(WGTDIR)/$(call wshort,$1)/$(call wshort,$1).dep: $(call wdir,$1)/$(call wshort,$1).dep | $(WGTDIR)/$(call wshort,$1)
	cp $$< $$@

$(WGTDIR)/$(call wshort,$1):
	mkdir -p $$@
endef

$(foreach w,$(WIDGETS),$(eval $(call WIDGET_RULES,$w)))

$(OBJDIR):
	mkdir -p $(OBJDIR)

# Copy the help sources into bin/ (upper-case 8.3 names) so the loader can
# rebuild the help files when the installed widget set changes.  Each
# widget's files go to the directory of its .wgt (bin name from WIDGETS,
# not the help file name); wgtsys.dhs goes to the widgets root.
deploy-helpsrc: wgtsys.dhs
	@if [ -n "$(strip $(WGT_HELP_MISSING))" ]; then echo "deploy-helpsrc: no .dhs help source in: $(strip $(WGT_HELP_MISSING))" >&2; exit 1; fi
	@mkdir -p $(WGTDIR)
	cp wgtsys.dhs $(WGTDIR)/WGTSYS.DHS
	@set -e; $(foreach w,$(WIDGETS),mkdir -p $(WGTDIR)/$(call wshort,$w); for f in $(wildcard $(call wdir,$w)/*.dhs $(call wdir,$w)/*.bhs); do cp "$$f" $(WGTDIR)/$(call wshort,$w)/"$$(basename "$$f" | tr a-z A-Z)"; done;)

-include $(OBJS:.o=.d) $(HOST_SOS:.so=.d)

clean:
	rm -f $(OBJS) $(OBJS:.o=.d) $(WGT_MODS) $(WGT_DEPS)
	-rmdir $(WGTDIR) 2>/dev/null
