/**
 * Chase UI
 */
#Const Version    "2017-04-28"
#Const ScriptName "ManiaApps/Nadeo/TrackMania/Chase.Script.txt"

// ---------------------------------- //
// Constants
// ---------------------------------- //
#Const C_LayerName "ChaseUI"

// ---------------------------------- //
// Libraries
// ---------------------------------- //
#Include "ManiaApps/Nadeo/Layers.Script.txt" as Layers

// ---------------------------------- //
// Functions
// ---------------------------------- //
// ---------------------------------- //
// Private
// ---------------------------------- //
// ---------------------------------- //
/** Get the manialink of the cahse UI
 *
 *  @return                           Chase UI manialink
 */
Text Private_GetChaseML() {
  declare PointsMax = 10;
  declare SizeX_Point = 4.;
  declare SizeX_Gauge = (PointsMax * (SizeX_Point + 1.)) - 1.;

  declare GapLeftML = "";
  declare GapRightML = "";
  for (I, 1, PointsMax) {
    GapLeftML ^= """<frameinstance pos="{{{(I-1)*-(SizeX_Point+1)}}} 0" z-index="{{{I}}}" modelid="framemodel-point-gap-left" />""";
    GapRightML ^= """<frameinstance pos="{{{(I-1)*(SizeX_Point+1)}}} 0" z-index="{{{I}}}" modelid="framemodel-point-gap-right" />""";
  }
  return """
<manialink version="3" name="ChaseUI">
<stylesheet>
  <style class="bg-dark" opacity="0.5" bgcolor="0b081b" />
  <style class="bg-blur" style="Bgs1" substyle="BgDialogBlur" opacity="0.1" />
  <style class="header-small" valign="bottom" opacity="0.5" colorize="fff" image="file://Media/Manialinks/Nadeo/Common/ScoresTable/HeaderSmall.dds" />
  <style class="header-big" valign="bottom" opacity="0.5" colorize="fff" image="file://Media/Manialinks/Nadeo/Common/ScoresTable/HeaderBig.dds" />
  <style class="text-default" textsize="3" textfont="OswaldMono" textcolor="fff" textemboss="1" />
</stylesheet>
<framemodel id="framemodel-point-gap-left">
  <quad z-index="0" size="{{{SizeX_Point}}} 6" halign="right" valign="center" class="bg-blur" />
  <quad z-index="1" size="{{{SizeX_Point}}} 6" halign="right" valign="center" opacity="0.2" bgcolor="000" id="quad-point-bg" />
  <quad z-index="2" size="{{{SizeX_Point}}} 6" halign="right" valign="center" opacity="0.8" bgcolor="fff" id="quad-point" />
</framemodel>
<framemodel id="framemodel-point-gap-right">
  <quad z-index="0" size="{{{SizeX_Point}}} 6" valign="center" class="bg-blur" />
  <quad z-index="1" size="{{{SizeX_Point}}} 6" valign="center" opacity="0.2" bgcolor="000" id="quad-point-bg" />
  <quad z-index="2" size="{{{SizeX_Point}}} 6" valign="center" opacity="0.8" bgcolor="fff" id="quad-point" />
</framemodel>
<frame id="frame-global">
  <frame pos="0 -60" z-index="1" id="frame-distance">
    <label halign="center" valign="center" class="text-default" id="label-distance" />
    <frame pos="-25 5" id="frame-distance-alt">
      <label z-index="1" halign="right" valign="center2" textsize="3" textemboss="1" textcolor="999" text="" id="label-car-left" />
      <quad z-index="0" valign="center" size="50 1.5" bgcolor="fff" id="quad-distance" />
      <quad pos="0.2 -0.2" z-index="-1" valign="center" size="50 1.5" bgcolor="000" id="quad-distance-bg" />
      <label pos="50.1 0" z-index="2" valign="center2" textsize="3" textemboss="1" textcolor="999" text="" id="label-car-right" />
    </frame>
  </frame>
  <frame z-index="0" pos="0 80" id="frame-header">
    <frame pos="-21 0">
      <quad z-index="0" size="15 0.6" rot="180" halign="right" class="header-small" id="quad-header-small" />
      <quad z-index="1" pos="15 0" size="5 0.6" rot="180" halign="right" class="header-big" id="quad-header-big" />
      <frame pos="10 3.5" z-index="4">
        <quad z-index="1" size="20 6" halign="center" valign="center" class="bg-blur" />
        <quad z-index="2" size="20 6" halign="center" valign="center" class="bg-dark" id="quad-team-color" />
        <label pos="0 -0.1" z-index="3" size="20 6" halign="center" valign="center2" textsize="4" text="0" class="text-default" id="label-round-points" />
      </frame>
      <frame pos="-1 3.5" z-index="2" id="frame-gap-points">
        {{{GapLeftML}}}
      </frame>
      <frame pos="-1 3.5" z-index="3" hidden="1" id="frame-gap-gauge">
        <quad z-index="0" size="{{{SizeX_Gauge}}} 6" halign="right" valign="center" class="bg-blur" />
        <quad z-index="1" size="{{{SizeX_Gauge}}} 6" halign="right" valign="center" opacity="0.2" bgcolor="000" id="quad-gauge-bg" />
        <quad z-index="2" size="{{{SizeX_Gauge}}} 6" halign="right" valign="center" opacity="0.8" bgcolor="fff" id="quad-gauge" />
      </frame>
    </frame>
    <frame pos="1 0">
      <quad z-index="1" size="5 0.6" rot="180" halign="right" class="header-big" id="quad-header-big" />
      <quad z-index="0" pos="5 0" size="15 0.6" rot="180" halign="right" class="header-small" id="quad-header-small" />
      <frame pos="10 3.5" z-index="4">
        <quad z-index="1" size="20 6" halign="center" valign="center" class="bg-blur" />
        <quad z-index="2" size="20 6" halign="center" valign="center" class="bg-dark" id="quad-team-color" />
        <label pos="0 -0.1" z-index="3" size="20 6" halign="center" valign="center2" textsize="4" text="0" class="text-default" id="label-round-points" />
      </frame>
      <frame pos="21 3.5" z-index="2" id="frame-gap-points">
        {{{GapRightML}}}
      </frame>
      <frame pos="21 3.5" z-index="3" hidden="1" id="frame-gap-gauge">
        <quad z-index="0" size="{{{SizeX_Gauge}}} 6" valign="center" class="bg-blur" />
        <quad z-index="1" size="{{{SizeX_Gauge}}} 6" valign="center" opacity="0.2" bgcolor="000" id="quad-gauge-bg" />
        <quad z-index="2" size="{{{SizeX_Gauge}}} 6" valign="center" opacity="0.8" bgcolor="fff" id="quad-gauge" />
      </frame>
    </frame>
  </frame>
</frame>
<script><!--
#Include "MathLib" as ML
#Include "TextLib" as TL

CTmMlPlayer GetOwner() {
  if (GUIPlayer != Null) return GUIPlayer;
  return InputPlayer;
}

Void SetDistanceVisibility(CUIConfig::EUISequence _UISequence, Ident _NextRelayPlayerId, CTmMlPlayer _Owner, CMlFrame _Frame_Distance) {
  if (_Frame_Distance == Null) return;

  _Frame_Distance.Visible = (_UISequence == CUIConfig::EUISequence::Playing && _NextRelayPlayerId != NullId && _Owner != Null && _NextRelayPlayerId != _Owner.Id);
}

Void UpdateRoundPoints(Integer _Clan, Integer _RoundPoints, CMlFrame _Frame_Header) {
  if (_Frame_Header == Null) return;

  if (_Frame_Header.Controls.existskey(_Clan - 1)) {
    declare Frame_Clan <=> (_Frame_Header.Controls[_Clan - 1] as CMlFrame);
    declare Label_RoundPoints <=> (Frame_Clan.GetFirstChild("label-round-points") as CMlLabel);
    Label_RoundPoints.Value = TL::ToText(_RoundPoints);
  }
}

Void UpdatePointsGap(Integer[Integer] _RoundPoints, Integer _MaxPointsGap, CMlFrame _Frame_Header) {
  if (_Frame_Header == Null) return;

  declare RoundPoints = [1 => 0, 2 => 0];
  for (Clan, 1, 2) {
    if (_RoundPoints.existskey(Clan)) RoundPoints[Clan] = _RoundPoints[Clan];
  }
  declare PointsGap = RoundPoints[1] - RoundPoints[2];

  foreach (Key => Control in _Frame_Header.Controls) {
    declare Frame_Clan <=> (Control as CMlFrame);
    declare Frame_GapPoints <=> (Frame_Clan.GetFirstChild("frame-gap-points") as CMlFrame);
    declare Frame_GapGauge <=> (Frame_Clan.GetFirstChild("frame-gap-gauge") as CMlFrame);

    declare Clan = Key + 1;

    // Use gauge
    if (_MaxPointsGap > Frame_GapPoints.Controls.count) {
      declare Ratio = 0.;
      if (_MaxPointsGap != 0) Ratio = ML::Abs(PointsGap / (_MaxPointsGap * 1.));
      if (Ratio < 0.) Ratio = 0.;
      else if (Ratio > 1.) Ratio = 1.;

      declare Quad_Gauge <=> (Frame_GapGauge.GetFirstChild("quad-gauge") as CMlQuad);
      declare Quad_GaugeBg <=> (Frame_GapGauge.GetFirstChild("quad-gauge-bg") as CMlQuad);

      if ((Clan == 1 && PointsGap > 0) || (Clan == 2 && PointsGap < 0)) {
        Quad_Gauge.Size.X = Quad_GaugeBg.Size.X * Ratio;
      } else {
        Quad_Gauge.Size.X = 0.;
      }

      Frame_GapPoints.Visible = False;
      Frame_GapGauge.Visible = True;
    }
    // Use points
    else {
      Frame_GapPoints.Visible = True;
      Frame_GapGauge.Visible = False;

      foreach (Key => Control in Frame_GapPoints.Controls) {
        declare Frame_Point <=> (Control as CMlFrame);

        if (Key < _MaxPointsGap) {
          declare Quad_Point <=> (Frame_Point.GetFirstChild("quad-point") as CMlQuad);
          declare Point = Key + 1;

          if ((Clan == 1 && PointsGap > 0) || (Clan == 2 && PointsGap < 0)) {
            Quad_Point.Visible = (PointsGap >= Point);
          } else {
            Quad_Point.Visible = False;
          }
          Frame_Point.Visible = True;
        } else {
          Frame_Point.Visible = False;
        }
      }
    }
  }
}

main() {
  declare Frame_Distance <=> (Page.GetFirstChild("frame-distance") as CMlFrame);
  declare Label_Distance <=> (Frame_Distance.GetFirstChild("label-distance") as CMlLabel);
  declare Frame_DistanceAlt <=> (Page.GetFirstChild("frame-distance-alt") as CMlFrame);
  declare Label_CarLeft <=> (Frame_DistanceAlt.GetFirstChild("label-car-left") as CMlLabel);
  declare Label_CarRight <=> (Frame_DistanceAlt.GetFirstChild("label-car-right") as CMlLabel);
  declare Quad_Distance <=> (Frame_DistanceAlt.GetFirstChild("quad-distance") as CMlQuad);
  declare Quad_DistanceBg <=> (Frame_DistanceAlt.GetFirstChild("quad-distance-bg") as CMlQuad);
  declare Frame_Header <=> (Page.GetFirstChild("frame-header") as CMlFrame);

  declare netread Integer Net_Chase_PointsGap for Teams[0];
  declare netread Integer[Integer] Net_Chase_RoundPoints for Teams[0];
  declare netread Net_MAChase_HeaderIsVisible for Teams[0] = True;

  declare NextRelayLogin = "";
  declare NextRelayPlayerId = NullId;

  declare PrevUISequence = CUIConfig::EUISequence::None;
  declare PrevRelayLogin = "";
  declare PrevTeamColor = [0 => <-1., -1., -1.>, 1 => <-1., -1., -1.>];
  declare PrevRoundPoints = [1 => -2, 2 => -2];
  declare PrevPointsGap = -2;

  declare PrevHeaderIsVisible = False;
  Frame_Header.Visible = PrevHeaderIsVisible;

  while (True) {
    yield;

    declare Owner <=> GetOwner();

    if (PrevUISequence != UI.UISequence) {
      PrevUISequence = UI.UISequence;
      SetDistanceVisibility(UI.UISequence, NextRelayPlayerId, Owner, Frame_Distance);
    }

    if (PrevHeaderIsVisible != Net_MAChase_HeaderIsVisible) {
      PrevHeaderIsVisible = Net_MAChase_HeaderIsVisible;
      Frame_Header.Visible = Net_MAChase_HeaderIsVisible;
    }

    if (Owner != Null) {
      if (Teams.existskey(Owner.CurrentClan - 1)) {
        declare netread Net_MAChase_NextRelayLogin for Teams[Owner.CurrentClan - 1] = "";

        if (NextRelayLogin != Net_MAChase_NextRelayLogin) {
          NextRelayLogin = Net_MAChase_NextRelayLogin;

          if (NextRelayLogin == "") {
            NextRelayPlayerId = NullId;
          } else {
            foreach (Player in Players) {
              if (Player.User.Login == NextRelayLogin) {
                NextRelayPlayerId = Player.Id;
                break;
              }
            }
          }

          SetDistanceVisibility(UI.UISequence, NextRelayPlayerId, Owner, Frame_Distance);
        }
      }
      
      if (NextRelayPlayerId != NullId && Players.existskey(NextRelayPlayerId)) {
        declare NextRelayPlayer <=> Players[NextRelayPlayerId];
        declare Distance = ML::NearestInteger(ML::Distance(Owner.Position, NextRelayPlayer.Position));
        declare Speed = Owner.DisplaySpeed - NextRelayPlayer.DisplaySpeed;
        declare VisualSpeed = "";
        if (Speed > 150) VisualSpeed = "";
        else if (Speed > 50) VisualSpeed = "";
        else if (Speed >= 0) VisualSpeed = "";
        else if (Speed >= -50) VisualSpeed = "";
        else if (Speed >= -150) VisualSpeed = "";
        else VisualSpeed = "";
        Label_Distance.Value = Distance^"m "^VisualSpeed;

        declare Ratio = Distance / 250.;
        if (Ratio > 1.) Ratio = 1.;
        Quad_Distance.Size.X = 50. * Ratio;
        Quad_DistanceBg.Size.X = 50. * Ratio;
        Label_CarRight.RelativePosition_V3.X = Quad_Distance.Size.X + 0.1;
        Frame_DistanceAlt.RelativePosition_V3.X = Quad_Distance.Size.X * -0.5;
      }
    }

    if (PrevTeamColor[0] != Teams[0].ColorPrimary || PrevTeamColor[1] != Teams[1].ColorPrimary) {
      PrevTeamColor[0] = Teams[0].ColorPrimary;
      PrevTeamColor[1] = Teams[1].ColorPrimary;

      /*if (Owner != Null && Teams.existskey(Owner.CurrentClan)) {
        Quad_Distance.BgColor = Teams[Owner.CurrentClan].ColorPrimary * 0.9;
      }*/

      foreach (Team => Control in Frame_Header.Controls) {
        declare Frame_Team = (Control as CMlFrame);
        declare Quad_HeaderSmall <=> (Frame_Team.GetFirstChild("quad-header-small") as CMlQuad);
        declare Quad_HeaderBig <=> (Frame_Team.GetFirstChild("quad-header-big") as CMlQuad);
        declare Quad_TeamColor <=> (Frame_Team.GetFirstChild("quad-team-color") as CMlQuad);
        Quad_HeaderSmall.Colorize = Teams[Team].ColorPrimary;
        Quad_HeaderBig.Colorize = Teams[Team].ColorPrimary;
        Quad_TeamColor.BgColor = Teams[Team].ColorPrimary;

        declare Frame_GapPoints <=> (Frame_Team.GetFirstChild("frame-gap-points") as CMlFrame);
        foreach (Control in Frame_GapPoints.Controls) {
          declare Frame_Point <=> (Control as CMlFrame);
          declare Quad_PointBg <=> (Frame_Point.GetFirstChild("quad-point-bg") as CMlQuad);
          declare Quad_Point <=> (Frame_Point.GetFirstChild("quad-point") as CMlQuad);
          Quad_PointBg.BgColor = Teams[Team].ColorPrimary * 0.5;
          Quad_Point.BgColor = Teams[Team].ColorPrimary;
        }

        declare Frame_GapGauge <=> (Frame_Team.GetFirstChild("frame-gap-gauge") as CMlFrame);
        declare Quad_GaugeBg <=> (Frame_GapGauge.GetFirstChild("quad-gauge-bg") as CMlQuad);
        declare Quad_Gauge <=> (Frame_GapGauge.GetFirstChild("quad-gauge") as CMlQuad);
        Quad_GaugeBg.BgColor = Teams[Team].ColorPrimary * 0.5;
        Quad_Gauge.BgColor = Teams[Team].ColorPrimary;
      }
    }

    declare RoundPointsUdpdated = False;
    for (Clan, 1, 2) {
      if (Net_Chase_RoundPoints.existskey(Clan)) {
        if (PrevRoundPoints[Clan] != Net_Chase_RoundPoints[Clan]) {
          PrevRoundPoints[Clan] = Net_Chase_RoundPoints[Clan];
          UpdateRoundPoints(Clan, Net_Chase_RoundPoints[Clan], Frame_Header);
          RoundPointsUdpdated = True;
        }
      } else if (PrevRoundPoints[Clan] != 0) {
        PrevRoundPoints[Clan] = 0;
        UpdateRoundPoints(Clan, 0, Frame_Header);
        RoundPointsUdpdated = True;
      }
    }

    if (PrevPointsGap != Net_Chase_PointsGap || RoundPointsUdpdated) {
      PrevPointsGap = Net_Chase_PointsGap;
      UpdatePointsGap(Net_Chase_RoundPoints, Net_Chase_PointsGap, Frame_Header);
    }
  }
}
--></script>
</manialink>
""";
}
// ---------------------------------- //
// Public
// ---------------------------------- //
// ---------------------------------- //
/** Return the version number of the script
 *
 *  @return                           The version number of the script
 */
Text GetScriptVersion() {
  return Version;
}

// ---------------------------------- //
/** Return the name of the script
 *
 *  @return                           The name of the script
 */
Text GetScriptName() {
  return ScriptName;
}

// ---------------------------------- //
/// Unload the library
Void Unload() {

}

// ---------------------------------- //
/// Load the library
Void Load() {
  Unload();

  Layers::Create(C_LayerName, Private_GetChaseML());
}