% Copyright 2015-... Maïeul Rouquette
%
% Inspired by Paul Stanley http://tex.stackexchange.com/a/172777/7712
%
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% 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 Maïeul Rouquette
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{biblatex-opcit-booktitle}[2018/10/24 v1.9.0 Manage op. cit. when using subentry]
\RequirePackage{xpatch}
\RequirePackage{xkeyval}%

\newtoggle{opcit@booktitle@bibliography@shorttitle}%
\newtoggle{opcit@booktitle@bibliography@onlyshorttitle}%
\DeclareOptionX{bibliography}[]{\toggletrue{opcit@booktitle@bibliography@#1}}%
\ProcessOptionsX%

% Declaration of the entries concerned. Some package could have already add their own entry
\def\opcit@booktitle@entrytypes@novolume{}
\listadd\opcit@booktitle@entrytypes{inbook}
\listadd\opcit@booktitle@entrytypes{incollection}
\listadd\opcit@booktitle@entrytypes{inproceedings}
\listadd\opcit@booktitle@entrytypes{bookinbook}


\DeclareFieldFormat{bibhypertarget:crossref}{%
  \bibhypertarget{\iffootnote{f}{t}:\cbx@resetcount:\thefield{crossref}}{#1}}

\DeclareFieldFormat{bibhyperlink:crossref}{%
  \bibhyperlink{\iffootnote{f}{t}:\cbx@resetcount:\thefield{crossref}}{#1}}


\newbibmacro*{cite:seen:related}{%
  \ifboolexpr{test{\ifdefequal{\blx@imc@ifciteseen}{\blx@ifciteseen@context}} and togl{blx@footnote}}%Mode context + footnote?
  {%
   \xifinlistcs{\thefield{crossref}}{blx@fsee@\the\c@refsection}%
     {}%
     {\listcsxadd{blx@fsee@\the\c@refsection}{\thefield{crossref}}}%
  }%
  {%
   \xifinlistcs{\thefield{crossref}}{blx@bsee@\the\c@refsection}%
     {}%
     {\listcsxadd{blx@bsee@\the\c@refsection}{\thefield{crossref}}}%
  }%
}%


\newcommand{\ifrelatedunseen}[2]{%
  \ifboolexpr{test{\ifdefequal{\blx@imc@ifciteseen}{\blx@ifciteseen@context}} and togl{blx@footnote}}%Mode context + footnote?
  {%
   \xifinlistcs{\thefield{crossref}}{blx@fsee@\the\c@refsection}%
   {#2}%
   {#1}%
  }%
  {%
   \xifinlistcs{\thefield{crossref}}{blx@bsee@\the\c@refsection}%
   {#2}%
   {#1}%
  }%
}%



\RequirePackage{ltxcmds}
\newcommand{\opcit@booktitle@failpatch}[2]{%
  \PackageError{opcit-booktitle}{Fail to patch `#1` bibmacro (#2)}{}%
}

% verbose-trad-1 and verbose-trad2
\ifboolexpr{%
  test{\ltx@iffileloaded{verbose-trad2.cbx}}%
  or test{\ltx@iffileloaded{verbose-trad1.cbx}}%
  }{%
  \xpatchbibmacro{cite}%
    {\usebibmacro{cite:full}%
         \usebibmacro{cite:save}}%
    {\usebibmacro{cite:test:ifrelated}}%
    {}%
    {\opcit@booktitle@failpatch{cite}{verbose-trad1.cbx or verbose-trad2.cbx}}%
}%
{}

% verbose-trad3. Not that lines must be applied AFTER the previous one
\ltx@iffileloaded{verbose-trad3.cbx}{%
  \xpatchbibmacro{cite}%
    {\usebibmacro{cite:full}}%
    {\usebibmacro{cite:test:ifrelated:verbose-trad3}}%
    {}%
    {\opcit@booktitle@failpatch{cite}{verbose-trad3.cbx}}%
}{}

\newbibmacro*{cite:test:ifrelated}%
      {\ifboolexpr {%
         test {\iffieldundef{crossref}}%
         or not (test {\xifinlist{\thefield{entrytype}}{\opcit@booktitle@entrytypes}})}%
       {\usebibmacro{cite:full}%
        \usebibmacro{cite:save}}%
       {\ifrelatedunseen%
        {\printtext[bibhypertarget:crossref]{%
         \usebibmacro{cite:seen:related}%
         \usebibmacro{cite:full}%
         \usebibmacro{cite:save}}}%
        {\usebibmacro{related:info}}}}

\newbibmacro*{cite:test:ifrelated:verbose-trad3}%
      {\ifboolexpr {%
         test {\iffieldundef{crossref}}%
         or not (test {\xifinlist{\thefield{entrytype}}{\opcit@booktitle@entrytypes}})}%
       {\usebibmacro{cite:full}%
        }%
       {\ifrelatedunseen%
        {\printtext[bibhypertarget:crossref]{%
         \usebibmacro{cite:seen:related}%
         \usebibmacro{cite:full}%
         }}%
        {\usebibmacro{related:info}}}}

% Here an hack to use the short form of the booktitle without recurring to a .dbx file in order to define new fields (because recurring to a .dbx file for such feature is complex for a little feature).
% The related:info:booktitle macro change the booktitle field to the shorttitle field of the parent entry.
% The related:info calls this macro and them call the driver of the main entry.

\newbibmacro*{related:info:booktitle}{%
  \undef\shortbooktitle%
  \undef\bookentrytype%
  \entrydata{\thefield{crossref}}{%
    \savefield{shorttitle}{\shortbooktitle}%
    \savefield{entrytype}{\bookentrytype}%
  }%
  \ifdef{\shortbooktitle}%
  {%
    \iffieldundef{crossref}%
    {}%
    {%
      \restorefield{booktitle}{\shortbooktitle}%
      \clearfield{booksubtitle}%
    }%
  }%
  {}%
}%

\newbibmacro*{related:info}{%
  \usebibmacro{related:info:booktitle}%
  \usebibmacro{cite:full:citepages}%
  \printtext[bibhypertarget]{\usedriver%
    {\DeclareNameAlias{sortname}{default}}%
    {inbook:rel:\blx@cbxfile}}%
}

\DeclareBibliographyDriver{inbook:rel:verbose-trad1}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \ifthenelse{\ifciteidem\AND\NOT\boolean{cbx:noidem}}%
    {\usebibmacro{cite:idem}}%
    {\ifnameundef{labelname}%
      {}%
      {\usebibmacro{cite:name}}%
    }%
  \newblock%
  \usebibmacro{title}%
  \newunit
  \printlist{language}%
  \newunit\newblock
  \usebibmacro{byauthor}%
  \newunit\newblock
  \usebibmacro{in:}%
  \printtext[bibhyperlink:crossref]{%
    \usebibmacro{inbook:rel:bookauthor}%
    \usebibmacro{maintitle+booktitle}%
    \newunit\newblock
    \usebibmacro{byeditor+others}%
    \newunit%
    \iffieldundef{maintitle}%
      {\xifinlist{\thefield{entrytype}}{\opcit@booktitle@entrytypes@novolume}%
       {}%
       {%
         \printfield{volume}%
         \printfield{part}}%
       }%
      {}%
    \newunit%
    \restorefield{entrytype}{\bookentrytype}%
    \bibstring[\mkibid]{opcit}%
  }%
  \newunit\newblock
  \usebibmacro{chapter+pages}%
  \newunit\newblock
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}


\DeclareBibliographyDriver{inbook:rel:verbose-trad2}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \ifthenelse{\ifciteidem\AND\NOT\boolean{cbx:noidem}}%
    {\usebibmacro{cite:idem}}%
    {\usebibmacro{author/translator+others}\setunit{\labelnamepunct}}%
  \newblock%
  \usebibmacro{title}%
  \newunit
  \printlist{language}%
  \newunit\newblock
  \usebibmacro{byauthor}%
  \newunit\newblock
  \usebibmacro{in:}%
  \printtext[bibhyperlink:crossref]{%
    \usebibmacro{inbook:rel:bookauthor}%
    \usebibmacro{maintitle+booktitle}%
    \newunit\newblock
    \usebibmacro{byeditor+others}%
    \newunit%
    \iffieldundef{maintitle}%
      {\xifinlist{\thefield{entrytype}}{\opcit@booktitle@entrytypes@novolume}%
       {}%
       {%
         \printfield{volume}%
         \printfield{part}}%
       }%
      {}%
    \newunit%
    \restorefield{entrytype}{\bookentrytype}%
    \bibstring[\mkibid]{opcit}%
  }%
  \newunit\newblock
  \usebibmacro{chapter+pages}%
  \newunit\newblock
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}

\DeclareBibliographyDriver{inbook:rel:verbose-trad3}{%
  \usebibmacro{bibindex}%
  \usebibmacro{begentry}%
  \printnames{labelname}%
  \setunit*{\printdelim{nametitledelim}}%
  \usebibmacro{title}%
  \newunit
  \printlist{language}%
  \newunit\newblock
  \usebibmacro{byauthor}%
  \newunit\newblock
  \usebibmacro{in:}%
  \printtext[bibhyperlink:crossref]{%
    \usebibmacro{inbook:rel:bookauthor}%
    \usebibmacro{maintitle+booktitle}%
    \newunit\newblock
    \usebibmacro{byeditor+others}%
    \newunit%
    \iffieldundef{maintitle}%
      {\xifinlist{\thefield{entrytype}}{\opcit@booktitle@entrytypes@novolume}%
       {}%
       {%
         \printfield{volume}%
         \printfield{part}}%
       }%
      {}%
  }%
  \newunit\newblock
  \usebibmacro{chapter+pages}%
  \newunit\newblock
  \setunit{\bibpagerefpunct}\newblock
  \usebibmacro{pageref}%
  \newunit\newblock
  \iftoggle{bbx:related}
    {\usebibmacro{related:init}%
     \usebibmacro{related}}
    {}%
  \usebibmacro{finentry}}

\newbibmacro{inbook:rel:bookauthor}{%
    \ifnameundef{bookauthor}%
      {}
      {%
      \usebibmacro{bybookauthor}%
      \setunit{\labelnamepunct}\newblock%
      }%
}

% Patching begenentry macro to apply bibliography option
\xpretobibmacro{begentry}%
  {%
    \ifbibliography%
      {\usebibmacro{opcitbooktitle:bibliography}}%
      {}%
  }%
  {}%
  {\opcit@booktitle@failpatch{begentry}{standard.bbx}}%

\newbibmacro{opcitbooktitle:bibliography}{%
  \iftoggle{opcit@booktitle@bibliography@shorttitle}%
    {\usebibmacro{related:info:booktitle}}%
    {}%
  \iftoggle{opcit@booktitle@bibliography@onlyshorttitle}{%
    \usebibmacro{related:info:booktitle}%
    \iffieldundef{crossref}{}{%
      \clearlist{publisher}%
      \clearlist{location}%
      \clearfield{series}%
      \clearfield{number}%
      \clearfield{year}%
      \clearfield{month}%
      \clearfield{day}%
      }%
    }{}%
}%
\endinput
