%% file: chordbars.sty
%% Copyright 2018-2024 M. Sebastien Kramm
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3c
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
%
% This work has the LPPL maintenance status `maintained'.
% 
% The Current Maintainer of this work is M. Sebastien Kramm
%
% This work consists of the files chordbars.sty and chordbars_manual.tex

% Home page: https://github.com/skramm/chordbars


% LOG:
% - 20240302: bugfixes with ycoef (version 1.3.2)
% - 20230331: added "ycoeff" parameter (version 1.3.1)
% - 2020525
% - added \addMeasures command
% - added starred version of chordbar environment

% TODO define command to have 1 chord per beat

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{chordbars}[2024-03-02 version 1.3.2]

\RequirePackage{tikz}
\RequirePackage{pgfmath}
\RequirePackage{tkz-euclide}

\usetikzlibrary{math,shapes}

\RequirePackage{calc}
\RequirePackage{ifthen}
\RequirePackage{wasysym} % for \fullmoon

\RequirePackage{relsize} % added on 2020-01-18

\def\vspacebefore{1ex}
\def\vspaceafter{1ex}

% This \dim command is used for diminished chords (until we find a nicer alternative)
\def\dim{\fullmoon}

\def\MajS{$\Delta$}
\def\addN{\relscale{0.8}\mdseries add9}
\def\susF{\relscale{0.8}\mdseries sus4}
%\def\add4{\relscale{0.8}\mdseries add4}

\newcommand{\songtitle}
{
%\tikzstyle{block} = [draw, rectangle, fill=blue!50,, text centered, minimum height=8mm,node distance=10em]
  \begin{center}%
	\begin{tikzpicture}[line width=1.5pt]
	\tikzstyle{block} = [rectangle, draw, text width=30em, text centered, minimum height=4em]
%	\tikzstyle{block} = [rectangle, draw, text centered, minimum height=4em]
%	\tikzstyle{block} = [rectangle, draw, minimum height=4em]
      	\node [block,font=\fontsize{20}{28}\selectfont\bfseries] (init) { \@title\\ \@author };
  	\end{tikzpicture}
  \end{center}%
  \par
  \vskip 1.5em
}

\newcounter{NumMesure}
\newcounter{NumPart}
\newcounter{CurrentBarInLine}
\newcounter{CurrentBar}
\newcounter{CurrentLine}

\xdef\tempoBPM{100}

\newcommand{\bpm}[1]
{
	\xdef\tempoBPM{#1}
	\rightline{Tempo=#1 BPM}
}

% "Beats Per Bar"
% default value
\xdef\bpb{4}

\newcommand{\bpbfour}
{
	\xdef\bpb{4}
}
\newcommand{\bpbthree}
{
	\xdef\bpb{3}
}

\newcommand{\resetchordbars}
{
	\setcounter{NumMesure}{0}
	\setcounter{NumPart}{0}
	\setcounter{CurrentBarInLine}{0}
}

\newcommand{\addMeasures}[1]
{
	\addtocounter{NumMesure}{#1}
	\setcounter{NumPart}{0}
	\setcounter{CurrentBarInLine}{0}
}

\newcommand{\printNbBars}
{
	\ifthenelse{\boolean{printBarNumber}}
	{
		Total number of bars: \arabic{NumMesure}, duration=\pgfmathparse{\theNumMesure/\tempoBPM*60*\bpb}\pgfmathresult {} s.
	}{}
}

% This boolean will be used to adjust horizontal position of the
% number of repetitions when a half bar is added (see \addHalfBar)
\newboolean{hasHalfBar}
%\setboolean{hasHalfBar}{false}  

\newboolean{printBarNumber}

\newcommand{\countbarsYes}
{
	\setboolean{printBarNumber}{true} 
}

\newcommand{\countbarsNo}
{
	\setboolean{printBarNumber}{false}
}

\def\barsize{1.6}%	
\def\ycoeff{0.8}%	
\def\delta{0.36}

\def\chordFontSize{\normalsize \bfseries}
\def\titleFontSize{\large \bfseries}

\xdef\NumberOfBarsPerLine{4}

% arg1: chord
% arg2: number of bars
% arg3: title
\newcommand{\chordline}[3]
{
	{\fontfamily{phv}\selectfont
	\noindent\ignorespaces %
	\vspace{\vspacebefore}
	\refstepcounter{NumMesure}%
	\refstepcounter{NumPart}%
	\begin{tikzpicture}[line width=1pt,x=1cm,y=-1cm]

% draw part title	
	\ifthenelse
		{\boolean{printBarNumber}}	
		{
			\draw (0,-\barsize*.2) node [anchor=west, align=left,font=\titleFontSize]
				{- Part \theNumPart: #3};
			\draw (-.3,.5*\barsize) node
				{\bf \theNumMesure};
		} 
		{
			\draw (0,-\barsize*.2) node [anchor=west, align=left,font=\titleFontSize] {#3};
		} 

	\draw (0,0) -- (#2*\barsize,0);               % horizontal lines
	\draw (0,\barsize*\ycoeff) -- (#2*\barsize,\barsize*\ycoeff);

	\draw (0,0) -- (0,\barsize*\ycoeff);                  % first vertical line
	\draw (\barsize,0) -- (\barsize,\barsize*\ycoeff);    % second vertical line
	\draw (\barsize/2,\ycoeff*\barsize/2) node [font=\chordFontSize]{#1};      % chord name

	\foreach \k in {2,...,{#2}}
	{
		\draw (\k*\barsize,0) -- (\k*\barsize,\barsize*\ycoeff);

		\pgfmathsetmacro{\Axa}{(\k-1)*\barsize+\delta*\barsize}
		\pgfmathsetmacro{\Axb}{\k*\barsize-\delta*\barsize}
		\pgfmathsetmacro{\Aya}{(1-\delta)*\barsize*\ycoeff}
		\pgfmathsetmacro{\Ayb}{\delta*\barsize*\ycoeff}

		\coordinate (A) at (\Axa,\Ayb);
		\coordinate (B) at (\Axb,\Aya);

		\fill (A) circle[radius=2pt];
		\fill (B) circle[radius=2pt];
		\draw [thick] (\Axa,\Aya) -- (\Axb,\Ayb); % Draw "repeat" symbol
	}					
				
	\end{tikzpicture}
	}
	\addtocounter{NumMesure}{#2}
	\addtocounter{NumMesure}{-1}
}

%==========================================================================
% main environment, has 2 mandatory arguments
% arg 1 (#2 inside): total number of 4 beat bars (4, 8, ...)
% arg 2 {#3 inside}: part name (can be empty)
% optional arg: nb of repetitions (default is 1)

% starred version: does not print the grid ! Only does the counters update, and prints these
\newenvironment{chordbar*}[3][1]
{
	\refstepcounter{NumPart}
	\refstepcounter{NumMesure}

	\@ifundefined{c@TmpA}{\newcounter{TmpA}}{}	
	\setcounter{TmpA}{#1*#2+\value{NumMesure}-1}

	\@ifundefined{c@TmpB}{\newcounter{TmpB}}{}
	\setcounter{TmpB}{#1*#2}

	\fontfamily{phv}\selectfont
	\noindent\ignorespaces %
%	\vspace{\vspacebefore}
			
	\begin{tikzpicture}
	\ifthenelse
		{\boolean{printBarNumber}}	
		{\pgfmathsetmacro{\xpos}{0.6}}
		{\pgfmathsetmacro{\xpos}{0}}
	
	\draw (0,0) node {}; % to align with other environments of the page

	% if we have repetitions, we print it and also the total number of bars
	\ifnum#1=1
			{\draw (\xpos,-\barsize*.2) node [anchor=west, align=left,font=\titleFontSize]	
				{- Part \theNumPart: #3, #2 bars, [ \theNumMesure {} $\rightarrow$ \theTmpA {} ] }; }
	\else
			{\draw (\xpos,-\barsize*.2) node [anchor=west, align=left,font=\titleFontSize]	
				{- Part \theNumPart: #3, #2 bars $\times$ #1 (\theTmpB), [ \theNumMesure {} $\rightarrow$ \theTmpA {} ] }; }
	\fi

	\end{tikzpicture}

	\setcounter{NumMesure}{\value{TmpA}}
}


\newenvironment{chordbar}[3][1]
{
    % "newline" command: just switches to next line
	\newcommand{\newchordline}
	{
		\setcounter{CurrentBarInLine}{0}
		\refstepcounter{CurrentLine}
	}

	\newcommand{\chordf}[1]%
	{
		\ifthenelse
			{\theCurrentBarInLine=\NumberOfBarsPerLine}
			{
				\refstepcounter{CurrentLine}
				\setcounter{CurrentBarInLine}{0}
			}
			{}
		\refstepcounter{CurrentBarInLine}%
		\pgfmathsetmacro{\x}{-\barsize/2+\theCurrentBarInLine*\barsize}
		\pgfmathsetmacro{\y}{\value{CurrentLine})*\barsize*\ycoeff+\barsize*\ycoeff/2}		
		\draw (\x,\y) node [font=\chordFontSize]{##1};%
	}%

	\newcommand{\chordh}[2]%
	{
		\ifthenelse
			{\theCurrentBarInLine=\NumberOfBarsPerLine}
			{
				\refstepcounter{CurrentLine}
				\setcounter{CurrentBarInLine}{0}
			}
			{}
		\refstepcounter{CurrentBarInLine}%
%		\typeout{CurrentBarInLine=\theCurrentBarInLine}
		\draw ( %
			{\barsize*(\theCurrentBarInLine-1)}, %
			{(\theCurrentLine+1)*\barsize*\ycoeff} %
		) %
		-- %
		( %
			{\theCurrentBarInLine*\barsize}, %
			{\theCurrentLine*\barsize*\ycoeff} %
		);		
		\draw (                                              % print first chord
			{-3*\barsize/4+\theCurrentBarInLine*\barsize},
			{\theCurrentLine*\barsize*\ycoeff+1*\barsize/4*\ycoeff}
		) node [font=\chordFontSize]{##1};
		\draw (                                               % print second chord
			{-\barsize/4+\theCurrentBarInLine*\barsize},
			{\theCurrentLine*\barsize*\ycoeff+3*\barsize/4*\ycoeff}
		) node [font=\chordFontSize]{##2};%	
	}
	
	\newcommand{\repeatBar}%
	{ %
		\ifthenelse
			{\theCurrentBarInLine=\NumberOfBarsPerLine}
			{
				\refstepcounter{CurrentLine}
				\setcounter{CurrentBarInLine}{0}
			}
			{}
		\refstepcounter{CurrentBarInLine}%
	
		\pgfmathsetmacro{\Axa}{(\theCurrentBarInLine-1)*\barsize+\delta*\barsize}
		\pgfmathsetmacro{\Axb}{\theCurrentBarInLine*\barsize-\delta*\barsize}
		\pgfmathsetmacro{\Aya}{(1-\delta)*\barsize*\ycoeff+\theCurrentLine*\barsize*\ycoeff}
		\pgfmathsetmacro{\Ayb}{\delta*\barsize*\ycoeff+\theCurrentLine*\barsize*\ycoeff}

		\coordinate (A) at (\Axa,\Ayb);
		\coordinate (B) at (\Axb,\Aya);

		\fill (A) circle[radius=2pt];
		\fill (B) circle[radius=2pt];
		\draw [thick] (\Axa,\Aya) -- (\Axb,\Ayb); %
	}%

	\newcommand{\repeatBarPair}%
	{ %
		\pgfmathsetmacro{\Axa}{\theCurrentBarInLine*\barsize+\delta*\barsize}
		\pgfmathsetmacro{\Axb}{(\theCurrentBarInLine+2)*\barsize-\delta*\barsize}
		\pgfmathsetmacro{\Aya}{(1-\delta)*\barsize*\ycoeff+\theCurrentLine*\barsize*\ycoeff}
		\pgfmathsetmacro{\Ayb}{\delta*\barsize*\ycoeff+\theCurrentLine*\barsize*\ycoeff}

		\coordinate (A) at (\Axa,\Ayb);
		\coordinate (B) at (\Axb,\Aya);

		\fill (A) circle[radius=2pt];
		\fill (B) circle[radius=2pt];
		\draw [thick] (\Axa,\Aya) -- (\Axb,\Ayb); %
		%
		\refstepcounter{CurrentBarInLine}
		\refstepcounter{CurrentBarInLine}
		\ifnum\value{CurrentBarInLine}=#2
		{
			\refstepcounter{CurrentLine}
			\setcounter{CurrentBarInLine}{0}
		}
		\fi		
	}%

	\newcommand{\addHalfBar}[1]%
	{
		\setboolean{hasHalfBar}{true}  
%
% The part might have some repetitions (arg 1), so we need to increment
% NumMesure by the number of repetions
		\addtocounter{NumMesure}{#1}
%		
		\refstepcounter{CurrentBarInLine}%
		
% diagonal line
%	\draw (\xa,\ya) -- (\xb,\yb);  A BUG HERE: investigate
		\draw
		(\theCurrentBarInLine*\barsize,{\theCurrentLine*\barsize*\ycoeff})
			--
		({(\theCurrentBarInLine-1)*\barsize},{(\theCurrentLine+1)*\barsize*\ycoeff});

% horizontal line
		\draw
		(\theCurrentBarInLine*\barsize,{\theCurrentLine*\barsize*\ycoeff})
			--
		({(\theCurrentBarInLine-1)*\barsize},{(\theCurrentLine)*\barsize*\ycoeff});

		\pgfmathsetmacro{\x}{-3*\barsize/4+\theCurrentBarInLine*\barsize}
		\pgfmathsetmacro{\y}{\value{CurrentLine})*\barsize*\ycoeff+\barsize/4}		
		\draw (\x,\y) node [font=\chordFontSize]{##1};%
	
	}

% HERE beginning of environment code		
%	\typeout{chordbar: START #3}

	\fontfamily{phv}\selectfont
	\setcounter{CurrentLine}{0}
	\setcounter{CurrentBarInLine}{0}
	\setcounter{CurrentBar}{0}
%	\setboolean{hasHalfBar}{true}  
	\setboolean{hasHalfBar}{false}  

	\refstepcounter{NumPart}%
	\refstepcounter{NumMesure}%
	\noindent\ignorespaces %
	\vspace{\vspacebefore}
%\resizebox{8cm}{!} {	
%	\scalebox{2}{
	\begin{tikzpicture}[line width=1pt,x=1cm,y=-1cm] %,scale=2]

	\ifthenelse
		{\boolean{printBarNumber}}	
		{\draw (-.3,.5*\barsize) node{\bf \theNumMesure};}
		{}

% compute the number of bars of the first line
	\xdef\NbBarsInitialLine{\NumberOfBarsPerLine}
	\ifthenelse
		{#2<\NumberOfBarsPerLine}
		{\xdef\NbBarsInitialLine{#2}}
		{}
			
% initial horizontal line
	\draw (0,0) -- (\NbBarsInitialLine*\barsize,0);

% draw part title	
	\ifthenelse
		{\boolean{printBarNumber}}	
		{\draw (0,-\barsize*.2) node [anchor=west, align=left,font=\titleFontSize]
			{- Part \theNumPart: #3};} 
		{\draw (0,-\barsize*.2) node [anchor=west, align=left,font=\titleFontSize]
			{- #3};} 

	\pgfmathtruncatemacro{\nblines}{(#2-1)/\NumberOfBarsPerLine+1}	
%	\typeout{chordbarl: nblines=\nblines}
	\foreach \line in {1,...,\nblines}
	{

		\draw (0,{\barsize*\ycoeff*(\line-1)}) -- (0,\line*\barsize*\ycoeff); % first vertical line
		\xdef\nbbars{\NumberOfBarsPerLine}
		\ifnum\line=\nblines
		{
			\pgfmathtruncatemacro{\nbbars}{#2-\NumberOfBarsPerLine*(\nblines-1)}
			\xdef\nbbars{\nbbars}
		}
		\fi
%		\typeout{chordbarl: nbbars=\nbbars}
		\foreach \k in {1,...,{\nbbars}}
		{
			\draw (\k*\barsize,{(\line-1)*\barsize*\ycoeff}) -- (\k*\barsize,{\line*\barsize*\ycoeff});
			\draw (0,{\line*\barsize*\ycoeff}) -- (\k*\barsize,{\line*\barsize*\ycoeff});
			
			\refstepcounter{CurrentBar}%
		}
	}
	\setcounter{NumMesure}{#1*#2+\value{NumMesure}-1}

% print the number of repetitions
	\ifnum#1=1 {} % do nothing
	\else
%--------------------
% THIS HERE IS WIP !	
		\ifthenelse
			 {\boolean{hasHalfBar}}
			 {\def\xoffset{2.0}}
			 {\def\xoffset{1.5}}
%--------------------			 
 		\ifthenelse
			{\boolean{printBarNumber}}
			{\draw (\NbBarsInitialLine*\barsize+\xoffset,0.5*\barsize) node {\Large \bf $\times$~#1};}
			{} 
	\fi
}%
{
%\typeout{chordbar: END}
	\end{tikzpicture}
%	} %
%	\par\noindent%
%	\ignorespacesafterend	
	\vspace{\vspaceafter}
}

% REMOVE INDENTATION
\setlength\parindent{0pt}

% so the user can use # without escaping
% see https://tex.stackexchange.com/questions/467562
\AtBeginDocument{\catcode`#=12 }

% additional code: redefine sharp and flat in text mode
% from https://tex.stackexchange.com/a/422249/11083
\let\OLDsharp\sharp
\renewcommand{\sharp}{\ensuremath{\OLDsharp}}
\let\OLDflat\flat
\renewcommand{\flat}{\ensuremath{\OLDflat}}

\endinput
  
