%% ======================================================== %%
%% orbitals.sty-- Package for drawing subshells and orbitals
%% Version: 1.0
%% Date: 2026-05-24
%% Author: Faris Hameed
%% Email: classsec81@gmail.com
%%  orbitals.sty  --  حزمة رسم الأغلفة الثانوية والأوربيتالات
%  رسم s, p, d, f مع توزيع الإلكترونات تلقائياً (قاعدة هوند + باولي) %%
%  الاستخدام يحتاج محرّك يدعم %%
%% Requires a compiler that supports TikZ 
%% pdfLaTeX / XeLaTeX / LuaLaTeX)
% ==========================================================
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{orbitals}[2026/05/24 v1.0 Atomic subshell/orbital diagrams]

% ----------------------------------------------------------
%  الجزء 1: المتطلبات
% ----------------------------------------------------------
\RequirePackage{tikz}
\RequirePackage{xcolor}
\usetikzlibrary{calc}

% mhchem اختياري (لكتابة الصيغ الكيميائية) — يُحمّل فقط إن لم يكن محمّلاً
\@ifpackageloaded{mhchem}{}{%
  \IfFileExists{mhchem.sty}{\RequirePackage[version=4]{mhchem}}{}%
}

% ----------------------------------------------------------
%  الجزء 2: الإعدادات القابلة للتخصيص (يمكن تغييرها بعد التحميل)
% ----------------------------------------------------------
\newcommand{\orb@boxwidth}{0.6}      % عرض كل مربع (أوربيتال)
\newcommand{\orb@boxheight}{0.8}     % ارتفاع المربع
\newcommand{\orb@gap}{0.9}           % الفراغ بين الأغلفة الثانوية
\newcommand{\orb@elcolor}{red}       % لون الإلكترونات (الأسهم)
\newcommand{\orb@linecolor}{black}   % لون إطار المربعات
\newlength{\orb@cwd}                  % لقياس عرض نص النواة

% --- إعدادات أنصاف الأسهم (الإلكترونات) ---
\newcommand{\orb@stem}{0.6}      % طول ساق السهم
\newcommand{\orb@head}{0.13}     % طول ضلع رأس السهم أفقياً
\newcommand{\orb@headdy}{0.25}    % نزول ضلع الرأس عمودياً
\newcommand{\orb@pairdx}{0.06}   % الإزاحة الأفقية بين سهمَي الزوج
\newcommand{\orb@arrowwidth}{0.75pt} % سُمك خط السهم
% أمر لتغيير شكل السهم عند الحاجة
\newcommand{\setElectronArrow}[2]{% {طول الساق}{سُمك الخط}
  \renewcommand{\orb@stem}{#1}\renewcommand{\orb@arrowwidth}{#2}}

% --- إعدادات التكبير/التصغير والمحاذاة للإدراج داخل السطر ---
\newcommand{\orb@scale}{1}        % معامل التكبير العام (1 = الحجم الطبيعي)
\newcommand{\setOrbitalScale}[1]{\renewcommand{\orb@scale}{#1}} % تغيير عام
% نمط المحاذاة العمودية (افتراضياً: توسيط على السطر) — يُطبّق على كل الرسوم
\tikzset{orbbaseline/.style={baseline=(current bounding box.center)}}
% \setOrbitalAlign{center}  -> توسيط عمودي على السطر (افتراضي، مناسب وسط النص)
% \setOrbitalAlign{bottom}  -> استقرار على خط الكتابة (سلوك TikZ الطبيعي)
\newcommand{\setOrbitalAlign}[1]{%
  \def\orb@tmpa{#1}\def\orb@tmpbottom{bottom}%
  \ifx\orb@tmpa\orb@tmpbottom
    \tikzset{orbbaseline/.style={baseline=0pt}}%
  \else
    \tikzset{orbbaseline/.style={baseline=(current bounding box.center)}}%
  \fi}

% --- تعريف أنصاف الأسهم كـ pics (يتبع اللون \orb@elcolor) ---
\tikzset{
  pics/halfarrowup/.style={code={%
    \draw[\orb@elcolor,line width=\orb@arrowwidth,line cap=round,line join=round]
      (0,0) -- (0,\orb@stem) -- (-\orb@head,\orb@stem-\orb@headdy);
  }},
  pics/halfarrowdown/.style={code={%
    \draw[\orb@elcolor,line width=\orb@arrowwidth,line cap=round,line join=round]
      (0,0) -- (0,-\orb@stem) -- (\orb@head,-\orb@stem+\orb@headdy);
  }},
}

% أوامر عامة لتغيير الإعدادات
\newcommand{\setOrbitalBox}[2]{\renewcommand{\orb@boxwidth}{#1}\renewcommand{\orb@boxheight}{#2}}
\newcommand{\setElectronColor}[1]{\renewcommand{\orb@elcolor}{#1}}
\newcommand{\setOrbitalGap}[1]{\renewcommand{\orb@gap}{#1}}

% ----------------------------------------------------------
%  الجزء 3: عدد الأوربيتالات (المربعات) لكل نوع غلاف ثانوي
%   s = 1   p = 3   d = 5   f = 7
% ----------------------------------------------------------
\newcommand{\orb@setboxcount}[1]{%
  \def\orb@nbox{0}%
  \ifx s#1\def\orb@nbox{1}\fi
  \ifx p#1\def\orb@nbox{3}\fi
  \ifx d#1\def\orb@nbox{5}\fi
  \ifx f#1\def\orb@nbox{7}\fi
}

% ----------------------------------------------------------
%  الجزء 4: رسم غلاف ثانوي واحد داخل tikzpicture
%   \orb@drawsub{xstart}{n}{type}{electrons}
%   - يرسم المربعات + الأسهم + التسمية (مثل 4p^5)
%   - يضبط \orb@width = العرض الكلي للغلاف المرسوم
% ----------------------------------------------------------
\newcommand{\orb@drawsub}[4]{%
  % #1 = نقطة البداية على المحور x
  % #2 = رقم الغلاف الرئيسي n
  % #3 = نوع الغلاف الثانوي (s/p/d/f)
  % #4 = عدد الإلكترونات
  % --- حفظ المعاملات في ماكروات (ضروري قبل استخدام \foreach) ---
  \def\orb@xs{#1}%
  \def\orb@nn{#2}%
  \def\orb@tt{#3}%
  \def\orb@ee{#4}%
  \orb@setboxcount{#3}%        عدد المربعات
  \pgfmathtruncatemacro{\orb@nb}{\orb@nbox}%
  \pgfmathtruncatemacro{\orb@e}{#4}%         عدد الإلكترونات
  % عدد المربعات المزدوجة (↑↓) = max(0, e - nbox)
  \pgfmathtruncatemacro{\orb@paired}{max(0,\orb@e-\orb@nb)}%
  % عدد المربعات المفردة (↑) = min(e,nbox) - paired
  \pgfmathtruncatemacro{\orb@single}{min(\orb@e,\orb@nb)-\orb@paired}%
  \pgfmathtruncatemacro{\orb@lim}{\orb@paired+\orb@single}%
  \pgfmathtruncatemacro{\orb@last}{\orb@nb-1}%
  % رسم المربعات والأسهم
  \foreach \orb@i in {0,...,\orb@last}{%
    \draw[\orb@linecolor]
      ({\orb@xs+\orb@i*\orb@boxwidth},0)
      rectangle ++(\orb@boxwidth,\orb@boxheight);
    \ifnum\orb@i<\orb@paired\relax
      % زوج إلكترونات: نصف سهم لأعلى (يسار) ونصف سهم لأسفل (يمين)
      \pic at ({\orb@xs+(\orb@i+0.5)*\orb@boxwidth-\orb@pairdx},%
               {0.5*\orb@boxheight-0.5*\orb@stem}) {halfarrowup};
      \pic at ({\orb@xs+(\orb@i+0.5)*\orb@boxwidth+\orb@pairdx},%
               {0.5*\orb@boxheight+0.5*\orb@stem}) {halfarrowdown};
    \else
      \ifnum\orb@i<\orb@lim\relax
        % إلكترون مفرد: نصف سهم لأعلى في المنتصف
        \pic at ({\orb@xs+(\orb@i+0.5)*\orb@boxwidth},%
                 {0.5*\orb@boxheight-0.5*\orb@stem}) {halfarrowup};
      \fi
    \fi
  }%
  % التسمية أعلى الغلاف: n type ^ electrons
  \pgfmathsetmacro{\orb@labelx}{\orb@xs+0.5*\orb@nb*\orb@boxwidth}%
  \node[above] at (\orb@labelx,\orb@boxheight+0.12)
    {\textbf{\ensuremath{\orb@nn\mathrm{\orb@tt}^{\orb@ee}}}};
  % تخزين العرض الكلي المستخدم
  \pgfmathsetmacro{\orb@tmpw}{\orb@nb*\orb@boxwidth}%
  \global\let\orb@width\orb@tmpw
}

% ----------------------------------------------------------
%  الجزء 5: \suborbital[<تكبير>]{n}{type}{electrons}
%   رسم غلاف ثانوي واحد قائم بذاته
%   مثال:  \suborbital{4}{p}{5}        ->  4p^5 بالحجم العام
%   مثال:  \suborbital[0.6]{4}{p}{5}   ->  مصغّر إلى 60%
% ----------------------------------------------------------
\NewDocumentCommand{\suborbital}{O{\orb@scale} m m m}{%
  \scalebox{#1}{%
  \begin{tikzpicture}[orbbaseline]
    \orb@drawsub{0}{#2}{#3}{#4}
  \end{tikzpicture}}%
}

% ----------------------------------------------------------
%  الجزء 6: محلّل صيغة مختصرة "4p5" -> n=4, type=p, e=5
%   الصيغة: <n مكوّن من خانة واحدة><type حرف واحد><electrons باقي النص>
% ----------------------------------------------------------
\def\orb@parse#1#2#3\@nil{%
  \orb@drawsub{\orb@xcur}{#1}{#2}{#3}%
}
% يستقبل عنصراً مفكوكاً مثل 4p5 ثم يمرّره للمحلّل
\newcommand{\orb@dolist}[1]{\orb@parse#1\@nil}

% ----------------------------------------------------------
%  الجزء 7: \electronconfig[<تكبير>]{قائمة}
%   رسم سلسلة أغلفة جنباً إلى جنب داخل لوحة واحدة
%   مثال:  \electronconfig{3d6,4s2,4p0}
%   مثال:  \electronconfig[1.3]{3d6,4s2,4p0}   % مكبّر
% ----------------------------------------------------------
\NewDocumentCommand{\electronconfig}{O{\orb@scale} m}{%
  \scalebox{#1}{%
  \begin{tikzpicture}[orbbaseline]
    \xdef\orb@xcur{0}%                موضع البداية الحالي
    \foreach \orb@item in {#2}{%
      % رسم العنصر الحالي بدءاً من \orb@xcur
      \expandafter\orb@dolist\expandafter{\orb@item}%
      % تقدّم الموضع: العرض المستخدم + الفراغ
      \pgfmathsetmacro{\orb@next}{\orb@xcur+\orb@width+\orb@gap}%
      \xdef\orb@xcur{\orb@next}%
    }%
  \end{tikzpicture}}%
}

% ----------------------------------------------------------
%  الجزء 8: \atomconfig[<النواة>][<المسافة>][<تكبير>]{<القائمة>}
%   - الاختياري 1: نص النواة (لُبّ غاز نبيل). افتراضياً فارغ
%   - الاختياري 2: المسافة قبل أول أوربيتال بالسنتيمتر (افتراضي 1)
%   - الاختياري 3: معامل التكبير (افتراضي = القيمة العامة)
%   - الإجباري   : قائمة الأغلفة
%   أمثلة:
%     \atomconfig[{\textsubscript{18}[Ar]}][1.2]{3d6,4s2,4p0}
%     \atomconfig[{\textsubscript{18}[Ar]}][1.2][0.7]{3d6,4s2,4p0} % مصغّر
% ----------------------------------------------------------
\NewDocumentCommand{\atomconfig}{O{} O{1} O{\orb@scale} m}{%
  \scalebox{#3}{%
  \begin{tikzpicture}[orbbaseline]
    \xdef\orb@xcur{0}%
    \def\orb@coretxt{#1}%
    \ifx\orb@coretxt\@empty\else
      \node[right,inner sep=0pt] at (0,0.5*\orb@boxheight) {\large\textbf{#1}};
      % المسافة قبل الأشكال (بالسنتيمتر) — يحدّدها المعامل الاختياري الثاني
      \xdef\orb@xcur{#2}%
    \fi
    \foreach \orb@item in {#4}{%
      \expandafter\orb@dolist\expandafter{\orb@item}%
      \pgfmathsetmacro{\orb@next}{\orb@xcur+\orb@width+\orb@gap}%
      \xdef\orb@xcur{\orb@next}%
    }%
  \end{tikzpicture}}%
}

% ----------------------------------------------------------
%  الجزء 9: \transitionseries[<تكبير>]{1|2|3}
%   إطار فارغ لصفوف العناصر الانتقالية (d, s, p)
%   1 -> 3d 4s 4p   |   2 -> 4d 5s 5p   |   3 -> 5d 6s 6p
% ----------------------------------------------------------
\NewDocumentCommand{\transitionseries}{O{\orb@scale} m}{%
  \ifcase#2\relax
    % case 0: لا شيء
  \or % 1
    \atomconfig[{\textsubscript{18}[Ar]}][1.5][#1]{3d0,4s0,4p0}%
  \or % 2
    \atomconfig[{\textsubscript{36}[Kr]}][1.5][#1]{4d0,5s0,5p0}%
  \or % 3
    \atomconfig[{\textsubscript{54}[Xe]\,4f\textsuperscript{14}}][2.5][#1]{5d0,6s0,6p0}%
  \fi
}

% ----------------------------------------------------------
%  الجزء 10: أمر اختصار للصيغ الكيميائية (يتطلب mhchem)
% ----------------------------------------------------------
\providecommand{\chem}[1]{\ensuremath{\ce{#1}}}

\endinput