#
# NoteCase hierarchical notes manager
# (http://notecase.sf.net)
#
# Usage: type "make help" for description of make options
#

VERSION=1.0.5

# define install prefix directory
prefix=/usr
# additional dirs
bindir=$(prefix)/bin
datadir=$(prefix)/share
# define top of RPM build area
topdir=/usr/src/redhat
# define source archive name
zipfile="notecase-$(VERSION)_src.zip"


# To profile NoteCase:
# 1. uncomment "PROFILE=..." line below 
# 2. comment out "LOPTIMIZE=..." line
# 3. comment out "strip $(BIN)/notecase" line
# 4. rebuild application
# 5. start and use application
# 6. profiling result is stored in a file "gmon.out" 
# 7. exec "gprof ./bin/notecase > aaa" to write results in a readable form into file "aaa"
#PROFILE=-pg

#DEBUG=-g -D_DEBUG
CXX=g++
CFLAGS=-Wall
FLAGS=$(CFLAGS)
BIN=./bin
OBJ=./bin

# using "--as-needed" to cut down link requirements (check by "readelf -d /usr/bin/notecase | grep NEEDED") 
LOPTIMIZE=-Os -s -Wl,--as-needed

# define compile/link command line with flags
CC=$(CXX) $(DEBUG) $(PROFILE) -DENABLE_NLS
LD=$(CXX) $(DEBUG) $(PROFILE) -ldl -export-dynamic $(LOPTIMIZE)

#
# define default project to build
#

all: notecase

#
# list of all objects to build (notecase dependencies)
#

OBJS= $(OBJ)/main.o $(OBJ)/support.o $(OBJ)/callbacks.o $(OBJ)/interface.o $(OBJ)/mru.o \
 $(OBJ)/EnumDirectory.o $(OBJ)/DocActionManager.o $(OBJ)/DocAction.o $(OBJ)/ExportDialog.o \
 $(OBJ)/OptionsDialog.o $(OBJ)/GuiLanguage.o $(OBJ)/TextSearch.o $(OBJ)/FileDialog.o \
 $(OBJ)/Dialog.o $(OBJ)/FindDialog.o $(OBJ)/PasswordDialog.o $(OBJ)/FilePath.o \
 $(OBJ)/IniFile.o $(OBJ)/blowfish.o $(OBJ)/DocumentIterator.o $(OBJ)/DocumentList.o \
 $(OBJ)/File64Enc.o $(OBJ)/File64.o $(OBJ)/FormatEncHtml.o $(OBJ)/FormatHtml.o \
 $(OBJ)/FormatGjots2.o $(OBJ)/HtmlParser.o $(OBJ)/NoteDocument.o $(OBJ)/NoteFormatIO.o \
 $(OBJ)/NoteNode.o $(OBJ)/SHA1.o $(OBJ)/eggtrayicon.o $(OBJ)/PortableTrayIcon.o \
 $(OBJ)/SingleInstance.o $(OBJ)/TreeView.o $(OBJ)/TextView.o $(OBJ)/MainWnd.o \
 $(OBJ)/FormatStickyNotes.o $(OBJ)/NodePropertiesDlg.o $(OBJ)/debug.o 

SRCPATH=./src/lib
GUIPATH=./src

GTKCFLAGS=`pkg-config --cflags gtk+-2.0 glib-2.0`
GTKLIBS=`pkg-config --libs gtk+-2.0 glib-2.0`


# link program binary
notecase: updatesrc $(OBJS)
	$(LD) $(OBJS) -o $(BIN)/notecase $(FLAGS) $(LDFLAGS) $(GTKLIBS)
	#strip $(BIN)/notecase

# compile individual objects

$(OBJ)/DocActionManager.o: $(SRCPATH)/DocActionManager.cpp $(SRCPATH)/DocActionManager.h
	$(CC) $(FLAGS) -c $(SRCPATH)/DocActionManager.cpp -o $(OBJ)/DocActionManager.o

$(OBJ)/DocAction.o: $(GUIPATH)/DocAction.cpp $(GUIPATH)/DocAction.h
	$(CC) $(FLAGS) -c $(GUIPATH)/DocAction.cpp -o $(OBJ)/DocAction.o $(GTKCFLAGS)

$(OBJ)/FindDialog.o: $(GUIPATH)/FindDialog.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/FindDialog.cpp -o $(OBJ)/FindDialog.o $(GTKCFLAGS)

$(OBJ)/ExportDialog.o: $(GUIPATH)/ExportDialog.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/ExportDialog.cpp -o $(OBJ)/ExportDialog.o $(GTKCFLAGS)

$(OBJ)/OptionsDialog.o: $(GUIPATH)/OptionsDialog.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/OptionsDialog.cpp -o $(OBJ)/OptionsDialog.o $(GTKCFLAGS)

$(OBJ)/EnumDirectory.o: $(GUIPATH)/lib/EnumDirectory.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/lib/EnumDirectory.cpp -o $(OBJ)/EnumDirectory.o

$(OBJ)/GuiLanguage.o: $(GUIPATH)/gui/GuiLanguage.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/gui/GuiLanguage.cpp -o $(OBJ)/GuiLanguage.o $(GTKCFLAGS)

$(OBJ)/TextSearch.o: $(GUIPATH)/lib/TextSearch.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/lib/TextSearch.cpp -o $(OBJ)/TextSearch.o $(GTKCFLAGS)

$(OBJ)/Dialog.o: $(GUIPATH)/gui/Dialog.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/gui/Dialog.cpp -o $(OBJ)/Dialog.o $(GTKCFLAGS)

$(OBJ)/PasswordDialog.o: $(GUIPATH)/PasswordDialog.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/PasswordDialog.cpp -o $(OBJ)/PasswordDialog.o $(GTKCFLAGS)

$(OBJ)/FileDialog.o: $(GUIPATH)/gui/FileDialog.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/gui/FileDialog.cpp -o $(OBJ)/FileDialog.o $(GTKCFLAGS)

$(OBJ)/main.o: $(GUIPATH)/main.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/main.cpp -o $(OBJ)/main.o $(GTKCFLAGS)

$(OBJ)/callbacks.o: $(GUIPATH)/callbacks.cpp $(GUIPATH)/callbacks.h
	$(CC) $(FLAGS) -c $(GUIPATH)/callbacks.cpp -o $(OBJ)/callbacks.o $(GTKCFLAGS)

$(OBJ)/interface.o: $(GUIPATH)/interface.cpp $(GUIPATH)/interface.h
	$(CC) $(FLAGS) -c $(GUIPATH)/interface.cpp -o $(OBJ)/interface.o $(GTKCFLAGS)

$(OBJ)/support.o: $(GUIPATH)/support.cpp $(GUIPATH)/support.h
	$(CC) $(FLAGS) -c $(GUIPATH)/support.cpp -o $(OBJ)/support.o $(GTKCFLAGS)

$(OBJ)/mru.o: $(GUIPATH)/mru.cpp $(GUIPATH)/mru.h
	$(CC) $(FLAGS) -c $(GUIPATH)/mru.cpp -o $(OBJ)/mru.o $(GTKCFLAGS)
		
$(OBJ)/IniFile.o: $(SRCPATH)/IniFile.cpp $(SRCPATH)/IniFile.h
	$(CC) $(FLAGS) -c $(SRCPATH)/IniFile.cpp -o $(OBJ)/IniFile.o
	
$(OBJ)/blowfish.o: $(SRCPATH)/blowfish.cpp $(SRCPATH)/blowfish.h
	$(CC) $(FLAGS) -c $(SRCPATH)/blowfish.cpp -o $(OBJ)/blowfish.o

$(OBJ)/DocumentIterator.o: $(SRCPATH)/DocumentIterator.cpp $(SRCPATH)/DocumentIterator.h
	$(CC) $(FLAGS) -c $(SRCPATH)/DocumentIterator.cpp -o $(OBJ)/DocumentIterator.o
  
$(OBJ)/DocumentList.o: $(SRCPATH)/DocumentList.cpp $(SRCPATH)/DocumentList.h
	$(CC) $(FLAGS) -c $(SRCPATH)/DocumentList.cpp -o $(OBJ)/DocumentList.o
  
$(OBJ)/FilePath.o: $(SRCPATH)/FilePath.cpp $(SRCPATH)/FilePath.h
	$(CC) $(FLAGS) -c $(SRCPATH)/FilePath.cpp -o $(OBJ)/FilePath.o
	
$(OBJ)/File64Enc.o: $(SRCPATH)/File64Enc.cpp $(SRCPATH)/File64Enc.h
	$(CC) $(FLAGS) -c $(SRCPATH)/File64Enc.cpp -o $(OBJ)/File64Enc.o
	
$(OBJ)/File64.o: $(SRCPATH)/File64.cpp $(SRCPATH)/File64.h
	$(CC) $(FLAGS) -c $(SRCPATH)/File64.cpp -o $(OBJ)/File64.o

$(OBJ)/FormatGjots2.o: $(SRCPATH)/FormatGjots2.cpp $(SRCPATH)/FormatGjots2.h
	$(CC) $(FLAGS) -c $(SRCPATH)/FormatGjots2.cpp -o $(OBJ)/FormatGjots2.o
	 
$(OBJ)/FormatEncHtml.o: $(SRCPATH)/FormatEncHtml.cpp $(SRCPATH)/FormatEncHtml.h
	$(CC) $(FLAGS) -c $(SRCPATH)/FormatEncHtml.cpp -o $(OBJ)/FormatEncHtml.o
  
$(OBJ)/FormatHtml.o: $(SRCPATH)/FormatHtml.cpp $(SRCPATH)/FormatHtml.h
	$(CC) $(FLAGS) -c $(SRCPATH)/FormatHtml.cpp -o $(OBJ)/FormatHtml.o
 
$(OBJ)/HtmlParser.o: $(SRCPATH)/HtmlParser.cpp $(SRCPATH)/HtmlParser.h
	$(CC) $(FLAGS) -c $(SRCPATH)/HtmlParser.cpp -o $(OBJ)/HtmlParser.o $(GTKCFLAGS)
  
$(OBJ)/NoteDocument.o: $(SRCPATH)/NoteDocument.cpp $(SRCPATH)/NoteDocument.h
	$(CC) $(FLAGS) -c $(SRCPATH)/NoteDocument.cpp -o $(OBJ)/NoteDocument.o
  
$(OBJ)/NoteFormatIO.o: $(SRCPATH)/NoteFormatIO.cpp $(SRCPATH)/NoteFormatIO.h
	$(CC) $(FLAGS) -c $(SRCPATH)/NoteFormatIO.cpp -o $(OBJ)/NoteFormatIO.o
  
$(OBJ)/NoteNode.o: $(SRCPATH)/NoteNode.cpp $(SRCPATH)/NoteNode.h
	$(CC) $(FLAGS) -c $(SRCPATH)/NoteNode.cpp -o $(OBJ)/NoteNode.o
  
$(OBJ)/SHA1.o: $(SRCPATH)/SHA1.cpp $(SRCPATH)/SHA1.h
	$(CC) $(FLAGS) -c $(SRCPATH)/SHA1.cpp -o $(OBJ)/SHA1.o

$(OBJ)/eggtrayicon.o: $(GUIPATH)/_unx/eggtrayicon.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/_unx/eggtrayicon.cpp -o $(OBJ)/eggtrayicon.o $(GTKCFLAGS)

$(OBJ)/PortableTrayIcon.o: $(GUIPATH)/PortableTrayIcon.cpp
	$(CC) $(FLAGS) -c $(GUIPATH)/PortableTrayIcon.cpp -o $(OBJ)/PortableTrayIcon.o $(GTKCFLAGS)

$(OBJ)/SingleInstance.o: $(GUIPATH)/_unx/SingleInstance.cpp $(GUIPATH)/_unx/SingleInstance.h
	$(CC) $(FLAGS) -c $(GUIPATH)/_unx/SingleInstance.cpp -o $(OBJ)/SingleInstance.o  $(GTKCFLAGS)

$(OBJ)/TreeView.o: $(GUIPATH)/TreeView.cpp $(GUIPATH)/TreeView.h
	$(CC) $(FLAGS) -c $(GUIPATH)/TreeView.cpp -o $(OBJ)/TreeView.o  $(GTKCFLAGS)

$(OBJ)/TextView.o: $(GUIPATH)/TextView.cpp $(GUIPATH)/TextView.h
	$(CC) $(FLAGS) -c $(GUIPATH)/TextView.cpp -o $(OBJ)/TextView.o  $(GTKCFLAGS)

$(OBJ)/MainWnd.o: $(GUIPATH)/MainWnd.cpp $(GUIPATH)/MainWnd.h
	$(CC) $(FLAGS) -c $(GUIPATH)/MainWnd.cpp -o $(OBJ)/MainWnd.o  $(GTKCFLAGS)
 
$(OBJ)/FormatStickyNotes.o: $(SRCPATH)/FormatStickyNotes.cpp $(SRCPATH)/FormatStickyNotes.h
	$(CC) $(FLAGS) -c $(SRCPATH)/FormatStickyNotes.cpp -o $(OBJ)/FormatStickyNotes.o  $(GTKCFLAGS)

$(OBJ)/NodePropertiesDlg.o: $(GUIPATH)/NodePropertiesDlg.cpp $(GUIPATH)/NodePropertiesDlg.h
	$(CC) $(FLAGS) -c $(GUIPATH)/NodePropertiesDlg.cpp -o $(OBJ)/NodePropertiesDlg.o  $(GTKCFLAGS)

$(OBJ)/debug.o: $(SRCPATH)/debug.cpp $(SRCPATH)/debug.h
	$(CC) $(FLAGS) -c $(SRCPATH)/debug.cpp -o $(OBJ)/debug.o $(GTKCFLAGS)

#
# help printout
#
help:
	@echo "Usage:"
	@echo "make             - builds application binaries"
	@echo "make clean       - delete built application and object files"
	@echo "make install     - install binaries into the official directories"
	@echo "make uninstall   - uninstall binaries from the official directories"
	@echo "make rpm         - create source and binary rpms from this source"
	@echo "make help        - prints this help"
	@echo "make poinstall   - create and install translation catalogs (.mo)"
	@echo "make pouninstall - uninstall translation catalogs (.mo)"
	@echo "make convertsrc  - convert source code files to DOS text format"
	@echo ""
	@echo "To create rpm as non-root user use this form (override path to your rpm build directory):"
	@echo "  make rpm topdir=~/rpm"

#
# install/uninstall application translations
# (dynamically listing available .po files inside ./po directory)
#

poinstall:
	@for i in `ls po/*.po`; do \
		rm -f po/messages.mo; \
		loc=`basename $$i`; \
		name_len=`expr length "$$loc"`; \
		name_len=`echo "$$name_len - 3" | bc`; \
		loc=`echo $$loc | cut -c -$$name_len`; \
		msgfmt $$i -o po/messages.mo; \
		install -D -m 644 po/messages.mo "$(prefix)/share/locale/$$loc/LC_MESSAGES/notecase.mo"; \
	done; \
	rm -f po/messages.mo; 
	@echo done installing translations

pouninstall:
	rm -vf $(prefix)/share/locale/*/LC_MESSAGES/notecase.mo
	@echo done uninstalling translations
	
#
# install application
#
install: notecase poinstall
	install -D -m 755 $(BIN)/notecase "$(bindir)/notecase"
	install -D -m 644 docs/help.ncd "$(datadir)/doc/notecase/help.ncd"
	install -D -m 644 docs/notecase.desktop "$(datadir)/applications/notecase.desktop"
	install -D -m 644 docs/notecase.xml "$(datadir)/mime/packages/notecase.xml"
	install -D -m 644 res/notecase.xpm "$(datadir)/icons/notecase.xpm"
#TOFIX: how to prevent "fedora-" prefix?
#	desktop-file-install --vendor=fedora \
#		--dir=$(datadir)/applications \
#		--add-category X-Fedora \
#		--add-category GTK \
#		--delete-original \
#		  $(datadir)/applications/notecase.desktop \
#		  $(datadir)/applications/notecase.desktop
	@echo done installing

#
# uninstall application
#
uninstall:	pouninstall
	rm -f  "$(bindir)/notecase"
	rm -f  "$(datadir)/applications/notecase.desktop"
	rm -f  "$(datadir)/icons/notecase.xpm"
	rm -rf "$(datadir)/doc/notecase"
	@echo done uninstalling

#
# build RPM and SRPM files (must be superuser)
#
rpm:	pack
	cp -f docs/notecase.spec $(topdir)/SPECS/notecase-$(VERSION).spec
	mv -f ../$(zipfile) $(topdir)/SOURCES
	cp -f ./res/notecase.xpm $(topdir)/SOURCES
	cp -f ./docs/notecase.desktop $(topdir)/SOURCES
	rpmbuild --define "_topdir $(topdir)" \
	         -ba "$(topdir)/SPECS/notecase-$(VERSION).spec"
	@echo Done, look for your RPMs and SRPM under $(topdir)

#
# pack sources in parent directory (need not be superuser)
#
pack: clean updatesrc
	# create zip file to be distributed
	cd ..; rm -f $(zipfile); zip -r $(zipfile) notecase-$(VERSION)

#
# - update version strings from makefile value
#   1. automaticaly update version information inside .spec file
#   2. automaticaly update "Source:" label inside .spec file
#   3. automaticaly update version information inside "config.h" header file
#   4. write $(prefix) value into the config.h
#
updatesrc:
	sed -i 's/Version:.*/Version:        $(VERSION)/' ./docs/notecase.spec
	sed -i 's/Source:.*/Source:         notecase-$(VERSION)_src.zip/' ./docs/notecase.spec
	sed -i 's/\#define APP_VER_STR .*/\#define APP_VER_STR "$(VERSION)"\r/' ./src/config.h
	sed -i 's:\#define INSTALL_PREFIX .*:\#define INSTALL_PREFIX "$(prefix)"\r:' ./src/config.h

#
# - convert sources to DOS text format (this is multiplatform project)
#
convertsrc:
	unix2dos -q -k $(SRCPATH)/*.cpp $(SRCPATH)/*.h $(GUIPATH)/*.cpp $(GUIPATH)/*.h $(GUIPATH)/gui/*.cpp $(GUIPATH)/gui/*.h

#
# - update Linux mime/desktop system
#
updatemime:
	update-mime-database "$(datadir)/mime/"
	update-desktop-database

#
# for debugging purposes
#
check: notecase
	@valgrind --leak-check=full --error-limit=no ./bin/notecase

#
# clean up the source tree
#
clean:
	@echo cleaning up
	rm -f $(OBJ)/*.o $(OBJ)/*.d $(BIN)/core.* $(BIN)/notecase ./gmon.out


.PHONY : all help poinstall pouninstall install uninstall rpm pack updatesrc updatemime clean
