% * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
% Copyright 2012-2014 Claudio Fiandrino
%
% 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 Claudio Fiandrino.

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{dynblocks}[2014/18/09 v0.2b A simple way to create dynamic blocks.]
\RequirePackage{tikz}
\RequirePackage{etoolbox}
\RequirePackage{xparse}

%% Colors definition and initial setting

\newcommand{\thecol}{blue!10}
\newcommand{\thebordercol}{blue}

%% Package options

% Customization colors
\DeclareOption{customcolors}{%
\def\setblockcolor#1{\def\@setcolor{#1}}
\def\@setcolor{blue!10}
\renewcommand{\thecol}{\@setcolor}

\def\setbordercolor#1{\def\@setbordercolor{#1}}
\def\@setbordercolor{blue}
\renewcommand{\thebordercol}{\@setbordercolor}

\def\setinnercolor#1{\def\@setinnercolor{#1}}
\def\@setinnercolor{white}

\def\setoutercolor#1{\def\@setoutercolor{#1}}
\def\@setoutercolor{blue!10}

\def\settopcolor#1{\def\@settopcolor{#1}}
\def\@settopcolor{white}

\def\setbottomcolor#1{\def\@setbottomcolor{#1}}
\def\@setbottomcolor{blue!10}

\def\setleftcolor#1{\def\@setleftcolor{#1}}
\def\@setleftcolor{white}

\def\setrightcolor#1{\def\@setrightcolor{#1}}
\def\@setrightcolor{blue!10}
}

% Customization colors adequate to the theme
\DeclareOption{getthemecolors}{%
% redefinition opaqueblock
\renewcommand{\thecol}{structure.fg!10}
\renewcommand{\thebordercol}{structure.fg}
% redefinition fancyblock
\def\@setinnercolor{white}
\def\@setoutercolor{structure.fg!10}
% redefinition vshadeblock
\def\@settopcolor{white}
\def\@setbottomcolor{structure.fg!10}
% redefinition oshadeblock
\def\@setleftcolor{white}
\def\@setrightcolor{structure.fg!10}
}

\newbool{rndcorners}
\boolfalse{rndcorners}
\DeclareOption{roundedcorners}{%
\booltrue{rndcorners}
}

\newbool{shadowed}
\boolfalse{shadowed}
\DeclareOption{shadow}{%
\usetikzlibrary{shadows}
\booltrue{shadowed}
}

\ProcessOptions

%% Opacity

\def\setvisopacity#1{\def\@visopacity{#1}}
\def\@visopacity{0.9}

\def\setinvopacity#1{\def\@invopacity{#1}}
\def\@invopacity{0.4}

\def\setshadowopacity#1{\def\@shadowopacity{#1}}
\def\@shadowopacity{0.4}

%% Alignment

\def\setalignment#1{\def\@alignment{#1}}
\def\@alignment{justify}

%% Word alert color

\def\setwordscolor#1{\def\@setwordscolor{#1}}
\def\@setwordscolor{blue}

\newcommand{\myalert}[1]{\textcolor{\@setwordscolor}{#1}}

%% Macro to save text and recall it afterwards

\newcounter{thistext}
\newcommand{\savetext}[2]{%
  «#1»%
  \addtocounter{thistext}{1}%
  \@namedef{thistext\thethistext}{#2}}
\newcommand{\printthistext}[1]{\@nameuse{thistext#1}}


%% Settings

\tikzset{visib/.style={rectangle,color=\thebordercol,fill=\thecol,text=black,draw,text opacity=\@visopacity, text width=#1,align=\@alignment}}
\tikzset{fancyvisib/.style={rectangle,color=\thebordercol,inner color=\@setinnercolor, outer color=\@setoutercolor,text=black,draw,text opacity=\@visopacity, text width=#1,align=\@alignment}}
\tikzset{vshadevisib/.style={rectangle,color=\thebordercol,top color=\@settopcolor, bottom color=\@setbottomcolor,text=black,draw,text opacity=\@visopacity, text width=#1,align=\@alignment}}
\tikzset{oshadevisib/.style={rectangle,color=\thebordercol,left color=\@setleftcolor, right color=\@setrightcolor,text=black,draw,text opacity=\@visopacity, text width=#1,align=\@alignment}}
\tikzset{invisib/.style={rectangle,color=gray,fill=gray!10,text=black,draw,text opacity=\@invopacity, text width=#1,align=\@alignment}}

%% Overlays

\tikzset{
    dyninvisible/.style={opacity=0,text opacity=0},
    dynvisible on/.style={dynalt=#1{}{dyninvisible}},
    dynalt/.code args={<#1>#2#3}{%
      \alt<#1>{\pgfkeysalso{#2}}{\pgfkeysalso{#3}} 
    },
  }
  
%% Rounded corners
\ifbool{rndcorners}{%true
\tikzset{visib/.append style={rounded corners}}
\tikzset{fancyvisib/.append style={rounded corners}}
\tikzset{vshadevisib/.append style={rounded corners}}
\tikzset{oshadevisib/.append style={rounded corners}}
\tikzset{invisib/.append style={rounded corners}}
}{%false
}

%% Definition of user commands and environment

\newenvironment{dynblock}{\begin{tikzpicture}}{\end{tikzpicture}}

\newlength\intdimension

\NewDocumentCommand{\opaqueblock}{r<> O{\textwidth} m}{%
\setlength{\intdimension}{\z@}
\addtolength{\intdimension}{#2}
\ifbool{shadowed}{% true
\node[visib=#2,dynvisible on=<{#1}>,drop shadow={opacity=\@shadowopacity,dynvisible on=<{#1}>}] (X) {\begingroup #3 \endgroup};
}{% false
\node[visib=#2,dynvisible on=<{#1}>] (X) {\begingroup #3 \endgroup};
}
\savetext{mytext}{#3}
}

\NewDocumentCommand{\fancyblock}{r<> O{\textwidth} m}{%
\setlength{\intdimension}{\z@}
\addtolength{\intdimension}{#2}
\ifbool{shadowed}{% true
\node[fancyvisib=#2,dynvisible on=<{#1}>,drop shadow={opacity=\@shadowopacity,dynvisible on=<{#1}>}] (X) {\begingroup #3 \endgroup};
}{% false
\node[fancyvisib=#2,dynvisible on=<{#1}>] (X) {\begingroup #3 \endgroup};
}
\savetext{mytext}{#3}
}

\NewDocumentCommand{\vshadeblock}{r<> O{\textwidth} m}{%
\setlength{\intdimension}{\z@}
\addtolength{\intdimension}{#2}
\ifbool{shadowed}{% true
\node[vshadevisib=#2,dynvisible on=<{#1}>,drop shadow={opacity=\@shadowopacity,dynvisible on=<{#1}>}] (X) {\begingroup #3 \endgroup};
}{% false
\node[vshadevisib=#2,dynvisible on=<{#1}>] (X) {\begingroup #3 \endgroup};
}
\savetext{mytext}{#3}
}

\NewDocumentCommand{\oshadeblock}{r<> O{\textwidth} m}{%
\setlength{\intdimension}{\z@}
\addtolength{\intdimension}{#2}
\ifbool{shadowed}{% true
\node[oshadevisib=#2,dynvisible on=<{#1}>,drop shadow={opacity=\@shadowopacity,dynvisible on=<{#1}>}] (X) {\begingroup #3 \endgroup};
}{% false
\node[oshadevisib=#2,dynvisible on=<{#1}>] (X) {\begingroup #3 \endgroup};
}
\savetext{mytext}{#3}
}

\NewDocumentCommand{\invblock}{r<>}{%
\ifbool{shadowed}{% true
\node[invisib=\intdimension,dynvisible on=<{#1}>,drop shadow={opacity=\@shadowopacity,dynvisible on=<{#1}>}] (X) {\printthistext{\thethistext}};
}{% false
\node[invisib=\intdimension,dynvisible on=<{#1}>] (X) {\printthistext{\thethistext}};
}
}

\NewDocumentCommand{\dynalert}{r<> m}{\alt<{#1}>{\pgfsetfillopacity{1}\myalert{#2}\pgfsetfillopacity{\@invopacity}}{#2}}

\endinput
