XRWS         !    ii  Bext_01.cat ext_01.dat readme.txt md/notifications.xml 1804 1448283418 055e571d6cc445945620d16b255f36cb
md/npc_shiptrader.xml 23844 1456071074 a88c4d4891bed8a6c5c6d13ac39c8421
md/shiprecycle.xml 1109 1456071078 a105b36e5141a89fb2c4742eb53302d0
t/0001-L007.xml 1038 1456330206 d2d043c5f1c32b2cb51acde279ff74be
t/0001-L033.xml 823 1456330024 008a8f3d667890e20b1eacbc8033077d
t/0001-L034.xml 791 1456330076 3be72f127fda526ae05d36c40dcf72bb
t/0001-L039.xml 799 1456330136 52e3532e85bbec150891d8768d9a816a
t/0001-L044.xml 762 1456233998 277c7045d7f895fc5f6cb5ab3ed74429
t/0001-L049.xml 815 1456330174 7860521f8be8a93f69da3117efab4163
t/0001.xml 762 1456329956 277c7045d7f895fc5f6cb5ab3ed74429
ui.xml 362 1448905542 4553c73cde33d91c13d9685d16536142
ui/ego_detailmonitorHelper.xml 197 1448905122 c9cd7d1755e04321e867207a4845c1a9
ui/shiprecycle/shiprecycle_menu_cost.lua 28935 1491483097 a2ec1066881b7a0511b41028cbaa5e5d
ui/shiprecycle/shiprecycle_menu_property.lua 30480 1449758662 69d7b5f55f2f889deb49516504faae82
<?xml version="1.0" encoding="utf-8"?>
<diff>

  <!-- Notifications remove the FormatThousands library if older -->
  <remove sel="/mdscript[@name='Notifications']['FormatThousands library already v2']/cues/library[@name='FormatThousands' and @version &lt; 2] " silent="true"/> 

  <!-- Notifications add the FormatThousands library if not present -->
  <add sel="/mdscript[@name='Notifications']['FormatThousands library already present']/cues[not (library[@name='FormatThousands'])]" silent="true">
    <library name="FormatThousands" version="2">
      <actions>
        <set_value name="$MoneyIn" exact="$Thousands"/>
        <set_value name="$FThousands" exact="''"/>
        <do_while value="($MoneyIn ge 1000) or ($MoneyIn le -1000)">
          <set_value name="$Remainder" exact="$MoneyIn%1000"/>
          <do_if value="$Remainder lt 0">
            <set_value name="$Remainder" exact="-$Remainder"/>
          </do_if>
          <do_if value="$Remainder lt 10" comment="add leading zeros">
            <set_value name="$FThousands" exact="{1001,106} + '00' + $Remainder + $FThousands"/>
          </do_if>
          <do_elseif value="$Remainder lt 100"  comment="add leading zero">
            <set_value name="$FThousands" exact="{1001,106} + '0' + $Remainder + $FThousands"/>
          </do_elseif>
          <do_else>
            <set_value name="$FThousands" exact="{1001,106} + $Remainder + $FThousands"/>
          </do_else>
          <set_value name="$MoneyIn" exact="($MoneyIn/1000)i"/>
        </do_while>
        <set_value name="$FThousands" exact="$MoneyIn + $FThousands"/>
        <remove_value name="$MoneyIn"/>
        <!-- <debug_text text="'In ' + $Thousands + ' Out ' + $FThousands"/> -->
      </actions>
    </library>
  </add>

</diff>
<?xml version="1.0" encoding="utf-8"?>
<diff>
  <!--	NPC_Shiptrader - DefaultComm menu option changed from "Sell a ship " to "Sell or Recycle a ship" around line 81	-->
  <replace sel="/mdscript[@name='NPC_Shiptrader']['Hijack Sell a Ship menu']/cues/cue[@name='Base']/cues/cue[@name='DefaultComm']/actions/do_else/do_if[@value='not $ship? and @$BuildModule.freedockslot']/add_player_choice_sub[@text='{1002,8006}']" >
    <add_player_choice_sub text="{360001,1}" position="bottom_left" section="cArch_sellship" choiceparam="[0, 0, 'player', 'recycleship', ['cArch_sellshipselected', $BuildModule, 'cArch_recycleship', $BuildModule.dockslot.component.docksize, $WareList, $actor]]" comment="Sell or Recycle a ship"/>
  </replace>

  <!--	NPC_Shiptrader - SectionHandler cArch_sellship use modified PropertyMenu around line 125	-->
  <replace sel="/mdscript[@name='NPC_Shiptrader']['Use modified PropertyMenu']/cues/cue[@name='Base']/cues/cue[@name='SectionHandler']/actions/do_elseif[@value=&quot;event.param == 'cArch_sellship'&quot;]/open_conversation_menu[@menu='PropertyMenu']" >
    <open_conversation_menu menu="ShipRecycle_PropertyMenu" param="event.param2" param2="event.param3" />
  </replace>

  <!--	NPC_Shiptrader - SectionHandler add section cArch_recycleship after cArch_sellshipselected around line 136	-->
  <add sel="/mdscript[@name='NPC_Shiptrader']['Add recycleship comms handling']/cues/cue[@name='Base']/cues/cue[@name='SectionHandler']/actions/do_elseif[@value=&quot;event.param == 'cArch_sellshipselected'&quot;]" pos="after" >
    <do_elseif value="event.param == 'cArch_recycleship'">
      <set_value name="$RecShip" exact="event.param2.{5}"/>

      <!-- Find the missiles and create an ammoplan -->
      <evaluate_ammo_storage object="$RecShip" type="missile" capacity="$launchercapacity" macros="$macrolist" amounts="$amountlist" wares="$warelist" />
      <debug_text text="'Missile Warelist entries ' + @$warelist.count + ' ' + @$warelist"/>
      <remove_value name="$Ammoplan"/>
      <create_list name="$Ammoplan"/>
      <do_all exact="@$warelist.count" counter="$Counter">
        <append_to_list name="$Ammoplan" exact="[$warelist.{$Counter}.objectmacro.id,$RecShip.ammostorage.{$warelist.{$Counter}.objectmacro}.count,$warelist.{$Counter}.id]"/>
      </do_all>
      <debug_text text="'Ammoplan is ' + $Ammoplan"/>
      <do_if value="not @event.param2.{14}">
        <append_to_list name="event.param2" exact="$Ammoplan"/>
      </do_if>

      <open_conversation_menu menu="ShipRecycle_CostMenu" param="event.param2" param2="event.param3" />
    </do_elseif>

    <do_elseif value="event.param == 'cArch_recycleshipselected'">
      <!-- <signal_cue_instantly cue="DumpParams" param="[event.param, event.param2, event.param3]"/> -->
      <add_conversation_view view="facenormal" />
      <set_value name="$soldship" exact="event.param2.{1}" />
      <set_value name="$soldshipprice" exact="event.param2.{2} * 1Cr" />
      <add_player_choice text="{360001,20}" position="top_left" section="cArch_recycleshipconfirmed" choiceparam="event.param2" comment="Yes, recycle this ship"/>
      <add_player_choice_return text="{1002,20}" position="bottom_right" comment="Back"/>
    </do_elseif>
  </add>

  <!--	NPC_Shiptrader - SectionHandler add section cArch_recycleshipconfirmed after cArch_sellshipconfirmed around line 264	-->
  <add sel="/mdscript[@name='NPC_Shiptrader']['Add recycleship comms handling']/cues/cue[@name='Base']/cues/cue[@name='SectionHandler']/actions/do_elseif[@value=&quot;event.param == 'cArch_sellshipconfirmed'&quot;]" pos="after" >
    <do_elseif value="event.param == 'cArch_recycleshipconfirmed'">
      <set_value name="$recycleship" exact="event.param2.{1}" />
      <set_value name="$price" exact="event.param2.{2}"/>
      <set_value name="$fraction" exact="-1.00" />
      <set_value name="$ship" exact="event.param2.{1}"/>
      <set_value name="$ship.pilot.$shiptrader_docking" exact="$BuildModule.freedockslot" />
      <debug_text text="$recycleship.name + ' selected for Recycling'"/>
      <debug_text text="$recycleship.name + ' is of size ' +  $recycleship.docksize"/>
      <debug_text text="$actor.name + ' has an ' + $actor.buildmodule.name"/>
      <debug_text text="$actor.buildmodule.name + ' is capable of docking ' + $BuildModule.dockslot.component.docksize + ' ships'"/>
      <set_value name="$TotalWares" exact="event.param2.{3}"/>
      <set_value name="$energycells" exact="event.param2.{4}"/>
      <set_value name="$foodrations" exact="event.param2.{5}"/>
      <set_value name="$ExtraWares" exact="event.param2.{6}"/>

      <!-- log current station cargo -->
      <set_value name="$results" exact="'Initial Station Cargo\n'"/>
      <do_all exact="$actor.container.cargo.count" counter="$Counter" reverse="true">
        <set_value name="$ThisWare" exact="$actor.container.cargo.list.{$Counter}" />
        <set_value name="$ThisWareID" exact="$ThisWare.id" />
        <set_value name="$ThisWareCount" exact="$actor.container.cargo.{$ThisWare}.count" />
        <set_value name="$results" exact="$results + $ThisWareID + ' ' + $ThisWareCount + '\n'"  />
      </do_all>
      <signal_cue_instantly cue="md.Ship_Recycle.LogWriter" param="[$results]"/>

      <!-- log the basic ship recycling wares -->
      <set_value name="$results" exact="$recycleship.name + ' - ' + $TotalWares.count + ' Wares\n' + $recycleship.macro + '\n'"/>
      <do_all exact="$TotalWares.count" counter="$Counter">
        <set_value name="$ThisWare" exact="$TotalWares.{$Counter}.{1}" />
        <set_value name="$ThisWareCount" exact="$TotalWares.{$Counter}.{2}" />
        <set_value name="$results" exact="$results + $ThisWare + ' - ' + $ThisWareCount + '\n'"/>
      </do_all>
      <signal_cue_instantly cue="md.Ship_Recycle.LogWriter" param="['Build wares for ' + $results]"/>

      <!-- remove resources needed for recycling -->
      <remove_cargo object="$actor.container" ware="ware.foodrations" exact="$foodrations" />
      <remove_cargo object="$actor.container" ware="ware.energycells" exact="$energycells" />

      <!-- Move recycling ship into dock -->
      <set_value name="$ship" exact="event.param2.{1}"/>
      <set_value name="$actor.$shiptrader_isbusy" exact="true" />
      <debug_text text="'Shiptrader_docking ' + $ship.pilot.$shiptrader_docking"/>
      <signal_cue cue="ListenOnShipDestroyed" />
      <do_if value="$ship.commander == player.primaryship">
        <signal_objects object="$ship" param="'dock at'" param2="$actor.container" param3="$BuildModule.dockslot"/>
      </do_if>
      <do_else>
        <start_script object="$ship.pilot" name="'move.dockat'">
          <param name="destination" value="$actor.container" />
          <param name="dockingslot" value="$BuildModule.dockslot" />
        </start_script>
      </do_else>
      <debug_text text="$ship.name + ' ' + $ship + ' told to move into dock'"/>
      <signal_cue cue="MoveSelectedShip" />

      <remove_value name="$energycells" />
      <remove_value name="$foodrations" />
      <remove_value name="$results" />
    </do_elseif>
  </add>

  <!--	NPC_Shiptrader - UpgradesFinished add section $recycleship? after $component? around line 447	-->
  <add sel="/mdscript[@name='NPC_Shiptrader']['Add recycleship handling to UpgradesFinished']/cues/cue[@name='Base']/cues/cue[@name='MoveSelectedShip']/cues/cue[@name='SelectedShipArrived']/cues/cue[@name='UpgradesFinished']/actions/do_elseif[@value=&quot;$component?&quot;]" pos="after" >
    <do_elseif value="$recycleship?">
      <debug_text text="$ship.name + ' now being recycled'"/>

      <!-- If player does not own shipyard then pay for ship -->
      <do_if value="$ship.owner != $actor.container.owner" >
        <set_value name="$Thousands" exact="($price)i"/>
        <include_actions ref="md.Notifications.FormatThousands"/>
        <debug_text text="$actor.container.name + ' not owned by player. Price ' + $FThousands" />
        <do_if value="@$price">
          <transfer_money from="$actor" to="player.entity" amount="($price)Cr" />
          <substitute_text text="$results" source="{360001,90}" comment="Received $MONEY$ Credits from $TRADER$ for $REASON$">
            <replace string="'$MONEY$'" with="$FThousands"/>
            <replace string="'$TRADER$'" with="$actor.typename + ' ' + $actor.name"/>
            <replace string="'$REASON$'" with="$ship.name"/>
          </substitute_text>
          <write_to_logbook category="upkeep" text="$results" />
          <debug_text text="'Received ' + $FThousands + ' Credits from Capital ShipDealer ' + $actor.name + ' for ' + $ship.name" />
          <remove_value name="$price"/>
        </do_if>
        <!-- change owner of ship -->
        <set_owner object="$ship" faction="faction.ownerless"/>
      </do_if>

      <!-- Sell and recreate crew -->
      <!-- crew are now sold and new NPC's created on the station -->

      <!-- after a version change this group will not be empty -->
      <do_if value="$ControlEntities?">
        <do_all exact="$ControlEntities.count" counter="$Counter">
          <debug_text text="'Cleanup ' + $Counter + '/' + $ControlEntities.count + ' ' + $ControlEntities.{$Counter}.type + ' ' + $ControlEntities.{$Counter}.name + ' ' + $ControlEntities.{$Counter}"/>
        </do_all>
        <signal_cue_instantly cue="RecycleCrew" param="[$ControlEntities, $actor, 1]" />
        <clear_group group="$ControlEntities"/>
      </do_if>

      <get_control_entities object="$ship" groupname="$ControlEntities"/>
      <signal_cue_instantly cue="RecycleCrew" param="[$ControlEntities, $actor, 0]" />

      <!-- recycle hull materials -->
      <set_value name="$results" exact="'Hull Wares added to ' + $actor.container.name + '\n'"/>
      <do_all exact="$TotalWares.count" counter="$Counter">
        <set_value name="$results" exact="$results + $TotalWares.{$Counter}.{1} + ' - ' + $TotalWares.{$Counter}.{2} + '\n'"/>
        <add_cargo object="$actor.container" ware="ware.{$TotalWares.{$Counter}.{1}}" exact="$TotalWares.{$Counter}.{2}" />
      </do_all>
      <signal_cue_instantly cue="md.Ship_Recycle.LogWriter" param="[$results]"/>

      <!-- recycle Drones, Ammo and Cargo -->
      <set_value name="$results" exact="'Extra Wares added to ' + $actor.container.name + '\n'"/>
      <do_all exact="$ExtraWares.count" counter="$Counter">
        <set_value name="$results" exact="$results + $ExtraWares.{$Counter}.{1} + ' - ' + $ExtraWares.{$Counter}.{2} + '\n'"/>
        <add_cargo object="$actor.container" ware="ware.{$ExtraWares.{$Counter}.{1}}" exact="$ExtraWares.{$Counter}.{2}" />
      </do_all>
      <signal_cue_instantly cue="md.Ship_Recycle.LogWriter" param="[$results]"/>

      <cancel_cue cue="DronesFinishedDelay" />
      <signal_cue_instantly cue="Tick" param="[1s, $ship, 1]"/>
    </do_elseif>
  </add>

  <!--	NPC_Shiptrader - SelectedShipArrived add cues RecycleCrew, Tick and Tock after UpgradesFinished around line 452	-->
  <add sel="/mdscript[@name='NPC_Shiptrader']['Add cues RecycleCrew, Tick and Tock']/cues/cue[@name='Base']/cues/cue[@name='MoveSelectedShip']/cues/cue[@name='SelectedShipArrived']/cues/cue[@name='UpgradesFinished']" pos="after" >
    <cue name="RecycleCrew" namespace="this" instantiate="true">
      <conditions>
        <event_cue_signalled />
      </conditions>
      <actions>
        <set_value name="$ControlEntities" exact="event.param.{1}"/>
        <set_value name="$ShipDealer" exact="event.param.{2}"/>
        <set_value name="$Shipyard" exact="event.param.{2}.container"/>
        <set_value name="$Cleanup" exact="event.param.{3}"/>

        <create_list name="$NPCSkills"/>
        <set_value name="$NPCSkills" exact="['boarding','combat','engineering','leadership','management','morale','navigation','science']"/>

        <set_value name="$TotalCrewFees" exact="0"/>
        <do_all exact="$ControlEntities.count" counter="$Counter">
          <do_if value="($Cleanup == 1) and ($ControlEntities.{$Counter}.container != $Shipyard)" >
            <set_value name="$results" exact="$ControlEntities.{$Counter}.type + ' ' + $ControlEntities.{$Counter}.name + ' ' + {1001,2951} + ' ' + $ControlEntities.{$Counter}.container.name + ' ' + {1001,2951} + ' ' + $ControlEntities.{$Counter}.container.zone.name + ' - ' + {360001,80}"
                       comment="NPCtype NPCname at station in zone - Skipped - working on a ship"/>
            <show_notification caption="{360001,70}" details="[$results]" timeout="3s" queued="true"/>
            <set_value name="$results" exact="$ShipDealer.typename + ' ' + $ShipDealer.name + $results"/>
            <signal_cue_instantly cue="md.Ship_Recycle.LogWriter" param="[$results]"/>
            <write_to_logbook category="upkeep" text="$results" />
            <continue/>
          </do_if>
          <debug_text text="$Counter + '/' + $ControlEntities.count + ' ' + $ControlEntities.{$Counter}.type + ' ' + $ControlEntities.{$Counter}.name + ' ' + $ControlEntities.{$Counter} + ' now being recycled'"/>
          <abort_scripts entity="$ControlEntities.{$Counter}"/>

          <!-- calculate hiring fee -->
          <set_value name="$actortype" exact="$ControlEntities.{$Counter}.type"/>
          <set_value name="$actor" exact="$ControlEntities.{$Counter}"/>
          <include_actions ref="md.NPC_Staff.FeeCalculation" />
          <do_all exact="md.$HireFees.count" counter="$i">
            <do_if value="md.$HireFees.{$i}.{1} == $actortype">
              <set_value name="$HireFeeParams" exact="md.$HireFees.{$i}" />
              <break />
            </do_if>
          </do_all>
          <!-- <debug_text text="'Min fee ' + $HireFeeParams.{2}+ ' Max fee ' + $HireFeeParams.{3}"/> -->
          <do_if value="$fee > $HireFeeParams.{3}">
            <set_value name="$fee" exact="$fee/100"/>
            <debug_text text="'Hire fee exceeds max ' + $HireFeeParams.{3} + ' divide by 100 ' + $fee"/>
          </do_if>
          <set_value name="$TotalCrewFees" exact="$fee" operation="add"/>
          <set_value name="$Thousands" exact="$fee"/>
          <include_actions ref="md.Notifications.FormatThousands"/>
          <set_value name="$results" exact="'Received ' + $FThousands + ' Credits from ' + $ShipDealer.typename + ' ' + $ShipDealer.name + ' for ' + $ControlEntities.{$Counter}.type.name + ' ' + $ControlEntities.{$Counter}.name + '\'s contract'"/>
          <debug_text text="$results" />
          <substitute_text text="$results" source="{360001,90}" comment="Received $MONEY$ Credits from $TRADER$ for $REASON$">
            <replace string="'$MONEY$'" with="$FThousands"/>
            <replace string="'$TRADER$'" with="$ShipDealer.typename + ' ' + $ShipDealer.name"/>
            <replace string="'$REASON$'" with="$ControlEntities.{$Counter}.type.name + ' ' + $ControlEntities.{$Counter}.name"/>
          </substitute_text>
          <write_to_logbook category="upkeep" text="$results" />
          <remove_value name="$fee"/>

          <!-- find location to recreate this crew member to -->
          <!-- try for bar first -->
          <find_dock_location name="$ActorDock" container="$Shipyard" size="tag.dock_p" dockpopulationtype="dockpopulationtype.bar"/>
          <do_if value="($ActorDock.component?) and ($ActorDock.numfreeactorslots? gt 0)" >
            <!--<debug_text text="'Room at the bar'"/>-->
          </do_if>
          <do_else>
            <!-- Now try for anywhere that takes people and has space -->
            <find_dock_location name="$Sdocks" container="$Shipyard" size="tag.dock_p" multiple="true" />
            <do_all exact="$Sdocks.count" counter="$CounterSd">
              <do_if value="$Sdocks.{$CounterSd}.numfreeactorslots gt 0">
                <set_value name="$ActorDock" exact="$Sdocks.{$CounterSd}"/>
                <!--<debug_text text="'Room at the ' + $ActorDock.component.name"/>-->
                <break/>
              </do_if>
            </do_all>
          </do_else>

          <!-- create a replacement NPC of same type on the shipyard -->
          <do_if value="$ActorDock?" >
            <create_cue_actor cue="this" name="$NewNPC" macro="$ControlEntities.{$Counter}.macro" />
            <set_object_name object="$NewNPC" name="$ControlEntities.{$Counter}.name" comment="rename NPC"/>

            <set_entity_type entity="$NewNPC" type="$ControlEntities.{$Counter}.type"/>
            <set_owner object="$NewNPC" faction="faction.friend"/>
            <create_platform_actor actor="$NewNPC" dockingbay="$ActorDock.component" type="$ControlEntities.{$Counter}.type" />

            <debug_text text="'Assigned ' + $NewNPC.type + ' ' + $NewNPC.name + ' ' + $NewNPC + ' to ' + $ActorDock.component.name" />
            <set_value name="$OldSkills" exact="$ControlEntities.{$Counter}.name + '\n'"/>
            <set_value name="$NewSkills" exact="$NewNPC.name + '\n'"/>
            <do_all exact="$NPCSkills.count" counter="$CounterS" >
              <set_value name="$OldSkills" exact="$OldSkills + $NPCSkills.{$CounterS} + ' - ' + $ControlEntities.{$Counter}.skill.{$NPCSkills.{$CounterS}} + '\n'"/>
              <set_skill entity="$NewNPC" type="skilltype.{$NPCSkills.{$CounterS}}" exact="$ControlEntities.{$Counter}.skill.{$NPCSkills.{$CounterS}}"/>
              <set_value name="$NewSkills" exact="$NewSkills + $NPCSkills.{$CounterS} + ' - ' + $NewNPC.skill.{$NPCSkills.{$CounterS}} + '\n'"/>
            </do_all>
            <!--<set_value name="$results" exact="$results + '\n\nAdding ' + $NewNPC.type + ' ' + $NewNPC.name + ' to ' + $ActorDock.component.name + ' at ' + $Shipyard.name"/>-->
            <substitute_text text="$logtext" source="{1016,72}" comment="Assigned $ENTITYTYPE$ $ENTITYNAME$ to (ship)$OBJECT$.">
              <replace string="'$ENTITYTYPE$'" with="$NewNPC.type"/>
              <replace string="'$ENTITYNAME$'" with="$NewNPC.name"/>
              <replace string="'$OBJECT$'" with="$ActorDock.component.name"/>
              <replace string="'in $ZONE$ '" with="''"/>
            </substitute_text>
            <set_value name="$results" exact="$results + '\n\n' + $logtext"/>

            <do_if value="$Cleanup == 1" >
              <set_value name="$title" exact="{360001,70}" comment="Convert NPC to Re-hireable"/>
            </do_if>
            <do_else>
              <set_value name="$title" exact="{360001,60} + ' NPC'" comment="Recycling NPC"/>
            </do_else>
            <show_notification caption="$title" details="[$results]" timeout="3s" queued="true"/>
            <!-- <signal_cue_instantly cue="md.Ship_Recycle.LogWriter" param="[$results]"/> -->
            <remove_value name="$logtext"/>
            <remove_value name="$OldSkills"/>
            <remove_value name="$NewSkills"/>
          </do_if>
          <do_else>
            <show_notification caption="{1010,11}"
                               details="[$results,'\nFailed to find anywhere to put recreated actor']"
                               timeout="5s" queued="true"/>
            <debug_text text="'Failed to find anywhere to put recreated actor'" />
          </do_else>
          <do_if value="$Cleanup == 1" >
            <debug_text text="'Destroying ' + $ControlEntities.{$Counter}.type + ' ' + $ControlEntities.{$Counter}.name + ' ' + $ControlEntities.{$Counter}" />
            <destroy_object object="$ControlEntities.{$Counter}"/>
          </do_if>
        </do_all>

        <!-- pay for all crew member contract -->
        <transfer_money from="$ShipDealer" to="player.entity" amount="($TotalCrewFees)Cr" />

        <remove_value name="$ControlEntities"/>
        <remove_value name="$NewNPC"/>
        <remove_value name="$NPCSkills"/>
        <remove_value name="$title"/>
      </actions>
    </cue>

    <cue name="Tick" namespace="this">
      <conditions>
        <event_cue_signalled />
      </conditions>
      <delay exact="event.param.{1}" />
      <actions>
        <set_value name="$ship" exact="event.param.{2}"/>
        <do_if value="$ship.hullpercentage > 0">
          <set_object_hull object="$ship" exact="$ship.hullpercentage - event.param.{3}" />
          <signal_cue_instantly cue="Tock" param="[event.param.{1}, $ship, event.param.{3}]"/>
        </do_if>
        <do_else>
          <signal_cue_instantly cue="RecycleFinished"/>
        </do_else>
        <reset_cue cue="this"/>
      </actions>
    </cue>

    <cue name="Tock" namespace="this">
      <conditions>
        <event_cue_signalled />
      </conditions>
      <delay exact="event.param.{1}" />
      <actions>
        <set_value name="$ship" exact="event.param.{2}"/>
        <do_if value="$ship.hullpercentage > 0">
          <set_object_hull object="$ship" exact="$ship.hullpercentage - event.param.{3}" />
        </do_if>
        <signal_cue_instantly cue="Tick" param="[event.param.{1}, $ship, event.param.{3}]"/>
        <reset_cue cue="this"/>
      </actions>
    </cue>
  </add>

  <!--	NPC_Shiptrader - Base add cues RecycleFinished, DelayedDestroyShip and LogWriter after BuildCancelled around line 645	-->
  <add sel="/mdscript[@name='NPC_Shiptrader']/cues/cue[@name='Base']/cues/cue[@name='BuildCancelled']" pos="after" >
    <cue name="RecycleFinished" instantiate="true">
      <conditions>
        <event_cue_signalled/>
      </conditions>
      <actions>
        <show_notification caption="$ship.name" details="[{360001,60} + ' - ' + {1001,25}]" timeout="10s" queued="true"
                           comment="Recycling - done" />

        <start_conversation actor="$actor" conversation="Speak" type="normal" convparam="1451" />
        <set_value name="$results" exact="{360001,60} + ' ' + {1001,2952} + ' ' + $ship.name + ' ' + {1001,2949} + ' ' + $ship.zone.name + ' - ' + {1001,25}"
                   comment="Recycling of SHIP$ in zone $SECTOR$ - done"/>
        <debug_text text="$results"/>
        <write_to_logbook category="upkeep" text="$results" />

        <set_value name="$results" exact="'Final Station Cargo\n'"/>
        <do_all exact="$actor.container.cargo.count" counter="$Counter" reverse="true">
          <set_value name="$ThisWare" exact="$actor.container.cargo.list.{$Counter}" />
          <set_value name="$ThisWareID" exact="$ThisWare.id" />
          <set_value name="$ThisWareCount" exact="$actor.container.cargo.{$ThisWare}.count" />
          <set_value name="$results" exact="$results + $ThisWareID + ' ' + $ThisWareCount + '\n'"  />
        </do_all>
        <signal_cue_instantly cue="md.Ship_Recycle.LogWriter" param="[$results]"/>

        <signal_cue_instantly cue="DelayedDestroyShip" param="[$ship]"/>
        <remove_value name="$ship" />
        <remove_value name="$actor.$shiptrader_isbusy" />
        <remove_value name="$buildcost" />
        <remove_cue_actor cue="this" />
        <remove_value name="$upgrade" />
        <remove_value name="$droneplan" />
        <remove_value name="$ammoplan" />
        <remove_value name="$component" />
        <remove_value name="$results" />
      </actions>
    </cue>

    <cue name="DelayedDestroyShip" namespace="this" instantiate="true">
      <conditions>
        <event_cue_signalled/>
      </conditions>
      <delay exact="20s"/>
      <actions>
        <debug_text text="event.param.{1}.name + ' destroyed'"/>
        <destroy_object object="event.param.{1}" />
        <remove_value name="$recycleship" />
      </actions>
    </cue>
  </add>

</diff>
<?xml version="1.0" encoding="utf-8" ?>
<mdscript name="Ship_Recycle" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="md.xsd">
  <cues>
    <cue name="LogWriter" namespace="this" instantiate="true">
      <conditions>
        <event_cue_signalled/>
      </conditions>
      <actions>
        <substitute_text text="$logtext" source="event.param.{1}">
          <replace string="'\n'" with="', '" />
        </substitute_text>
        <debug_text text="$logtext"/>
      </actions>
    </cue>

    <cue name="ShipRecycle_Logger" namespace="this" instantiate="true" comment="Remote logger for lua scripts avoids using DebugError" >
      <conditions>
        <event_ui_triggered screen="'ShipRecycle_Logger'" />
      </conditions>
      <actions>
        <do_if value="event.param3 != null" comment="4.00 RC2 or later">
          <debug_text text="event.param3"/>
        </do_if>
        <do_else>
          <debug_text text="event.param2" comment="earlier than 4.00 RC2"/>
        </do_else>
      </actions>
    </cue>
  </cues>
</mdscript>﻿<?xml version="1.0" encoding="UTF-8"?>
<!-- English v0.01	9th December 2015 jth -->

<language>
	<page id="360001" title="ShipRecycle" descr="Texts for ShipRecycle." voice="no">
	     <t id="1">Продать / Утилизировать</t>
         <t id="5">Утилизировать</t>
         <t id="10">Данный класс корабля нельзя утилизировать на </t>
         <t id="20">Да, утилизировать этот корабль</t>
		 <t id="30">Стоимость утилизации %s($Station/Ship_Name$)</t>
		 <t id="40">Не утили-тся - </t>
		 <t id="50">Переполнение</t>
		 <t id="60">Утилизация</t>
		 <t id="70">Конвертация NPC в нанимаемого </t>
		 <t id="80">Пропущено - работает на корабле</t>
		 <t id="90">Переведено $MONEY$ {1001,37} {10002,25} $TRADER$ за $REASON$</t>
		 <t id="100">Взнос за обработку груза - </t>
	</page>
</language>﻿<?xml version="1.0" encoding="UTF-8"?>
<!-- French v0.01	9th December 2015 jth -->

<language>
	<page id="360001" title="ShipRecycle" descr="Texts for ShipRecycle." voice="no">
	     <t id="1">Vendre ou Recycler un vaisseau</t>
         <t id="5">Recycler</t>
         <t id="10">Vous ne pouvez pas recycler - vaisseau ne rentre pas dans le </t>
         <t id="20">Oui, recycler ce vaisseau</t>
		 <t id="30">Coûts du recyclage pour %s($Station/Ship_Name$)</t>
		 <t id="40">Non recyclable - </t>
		 <t id="50">Excès</t>
		 <t id="60">Recyclage</t>
		 <t id="70">Convertir NPC pour Re-hireable</t>
		 <t id="80">Ignoré - travailler sur un vaisseau</t>
		 <t id="90">Reception de $MONEY$ {1001,37} {10002,25} $TRADER$ pour $REASON$</t>
		 <t id="100">Frais de manutention - </t>
	</page>
</language>﻿<?xml version="1.0" encoding="UTF-8"?>
<!-- Spanish v0.01	9th December 2015 jth -->

<language>
	<page id="360001" title="ShipRecycle" descr="Textos para ShipRecycle." voice="no">
	     <t id="1">Vender o reciclar una nave</t>
         <t id="5">Reciclar</t>
         <t id="10">No se puede reciclar - nave no encaja en el </t>
         <t id="20">Sí, reciclar esta nave</t>
		 <t id="30">Costes de reciclaje para %s($Station/Ship_Name$)</t>
		 <t id="40">No reciclable - </t>
		 <t id="50">Exceso</t>
		 <t id="60">Reciclaje</t>
		 <t id="70">Convertido NPC para Re-hireable</t>
		 <t id="80">Saltado - trabajando en una nave</t>
		 <t id="90">Recibido $MONEY$ {1001,37} {10002,25} $TRADER$ para $REASON$</t>
		 <t id="100">Manejo de Tarifa - </t>
	</page>
</language>﻿<?xml version="1.0" encoding="UTF-8"?>
<!-- Italian v0.01	9th December 2015 jth -->

<language>
	<page id="360001" title="ShipRecycle" descr="Testi per ShipRecycle." voice="no">
	     <t id="1">Vendi o Riciclare una nave</t>
         <t id="5">Riciclare</t>
         <t id="10">Non può riciclare - nave non rientra nel </t>
         <t id="20">Sì, riciclare questa nave</t>
		 <t id="30">I costi di riciclaggio per %s($Station/Ship_Name$)</t>
		 <t id="40">Non riciclabile - </t>
		 <t id="50">Eccesso</t>
		 <t id="60">Riciclaggio</t>
		 <t id="70">Convert NPC per Re-noleggiabile</t>
		 <t id="80">Saltato - a lavorare su una nave</t>
		 <t id="90">Ricevuti $MONEY$ {1001,37} {10002,25} $TRADER$ per $REASON$</t>
		 <t id="100">Tassa d'istruzione - </t>
	</page>
</language>﻿<?xml version="1.0" encoding="UTF-8"?>
<!-- English v0.01	9th December 2015 jth -->

<language>
	<page id="360001" title="ShipRecycle" descr="Texts for ShipRecycle." voice="no">
	     <t id="1">Sell or Recycle a ship</t>
         <t id="5">Recycle</t>
         <t id="10">Cannot Recycle - ship does not fit in the </t>
         <t id="20">Yes, recycle this ship</t>
		 <t id="30">Recycling costs for %s($Station/Ship_Name$)</t>
		 <t id="40">Not recyclable - </t>
		 <t id="50">Excess</t>
		 <t id="60">Recycling</t>
		 <t id="70">Convert NPC to Re-hireable</t>
		 <t id="80">Skipped - working on a ship</t>
		 <t id="90">Received $MONEY$ {1001,37} {10002,25} $TRADER$ for $REASON$</t>
		 <t id="100">Handling Fee - </t>
	</page>
</language>﻿<?xml version="1.0" encoding="UTF-8"?>
<!-- German v0.01	9th December 2015 jth -->

<language>
	<page id="360001" title="Ship Recycle" descr="Texte für ShipRecycle." voice="no">
	     <t id="1">Verkaufen oder Verwerten ein schiff</t>
         <t id="5">Verwerten</t>
         <t id="10">Kann nicht Verwerten - schiff nicht in der Passung </t>
         <t id="20">Ja, verwerten dieses schiff</t>
		 <t id="30">Recycling costs for %s($Station/Ship_Name$)</t>
		 <t id="40">Nicht recyclebar - </t>
		 <t id="50">Excess</t>
		 <t id="60">Verwertung</t>
		 <t id="70">Konvertieren NPC Re-hireable</t>
		 <t id="80">Sprungen - Arbeiten auf einem schiff</t>
		 <t id="90">Erhaltene $MONEY$ {1001,37} {10002,25} $TRADER$ für $REASON$</t>
		 <t id="100">Bearbeitungsgebühr - </t>
	</page>
</language>﻿<?xml version="1.0" encoding="UTF-8"?>
<!-- English v0.01	9th December 2015 jth -->

<language>
	<page id="360001" title="ShipRecycle" descr="Texts for ShipRecycle." voice="no">
	     <t id="1">Sell or Recycle a ship</t>
         <t id="5">Recycle</t>
         <t id="10">Cannot Recycle - ship does not fit in the </t>
         <t id="20">Yes, recycle this ship</t>
		 <t id="30">Recycling costs for %s($Station/Ship_Name$)</t>
		 <t id="40">Not recyclable - </t>
		 <t id="50">Excess</t>
		 <t id="60">Recycling</t>
		 <t id="70">Convert NPC to Re-hireable</t>
		 <t id="80">Skipped - working on a ship</t>
		 <t id="90">Received $MONEY$ {1001,37} {10002,25} $TRADER$ for $REASON$</t>
		 <t id="100">Handling Fee - </t>
	</page>
</language><?xml version="1.0" encoding="UTF-8"?>
<addon name="shiprecycle">
  <environment type="detailmonitor">
    <file name="ui/shiprecycle/shiprecycle_menu_property.lua" />
    <dependency name="ego_detailmonitorHelper" />
    <file name="ui/shiprecycle/shiprecycle_menu_cost.lua" />
    <dependency name="ego_detailmonitorHelper" />
  </environment>
</addon><addon name="ego_detailmonitorHelper" viewtype="detailmonitor">
  <file name="ui/shiprecycle/shiprecycle_menu_property.lua" />
  <file name="ui/shiprecycle/shiprecycle_menu_cost.lua" />
</addon>
-- section == cArch_recyclecost
-- param == { 0, 0, architect, buildership_or_module, component, macro, sequence, stage, upgradeplan, buildlimit, targethullfraction, upgradesonly, droneplan, ammoplan }

local menu = {
	name = "ShipRecycle_CostMenu",
	white = { r = 255, g = 255, b = 255, a = 100 },
	red = { r = 255, g = 0, b = 0, a = 100 },
	green = { r = 0, g = 255, b = 0, a = 100 }
}

local function init()
	Menus = Menus or { }
	table.insert(Menus, menu)
	if Helper then
		Helper.registerMenu(menu)
	end
end

function menu.cleanup()
	menu.architect = nil
	menu.buildership = nil
	menu.component = nil
	menu.macro = nil
	menu.sequence = nil
	menu.stage = nil
	menu.upgradeplan = nil
	menu.shipbuilding = nil
	menu.recycledship = nil
	menu.handlingcharge = nil
	menu.recyclewares = nil
	menu.recyclewaresextra = nil
	menu.recyclingPrereqsMet = nil
	menu.cost = nil
	menu.current = nil
	menu.buildlimit = nil
	menu.targethullfraction = nil
	menu.upgradesonly = nil
	menu.droneplan = {}
	menu.hasentries = nil
	menu.isokbuttonenabled = nil
	menu.neededresources = {}
	menu.infotable = nil
	menu.selecttable = nil
end

-- Menu member functions

function menu.buttonOK()
	local sellercontainer = GetContextByClass(menu.buildership, "container", true)
	if menu.recycledship then
		Helper.closeMenuForSubSection(menu, false, "cArch_recycleshipselected", { menu.component, math.floor(menu.cost * -1), menu.recyclewares, menu.energycells, menu.foodrations, menu.recyclewaresextra})
		menu.shipbuilding = false
	elseif menu.shipbuilding then
		for _, entry in ipairs(menu.droneplan) do
			RemoveCargo(sellercontainer, entry[3], entry[2])
		end
		local success = true
		local playerMoney = GetPlayerMoney()
		if playerMoney >= math.floor(menu.cost) then
			TransferPlayerMoneyTo(math.floor(menu.cost), menu.architect)
		else
			success = false
		end
		if menu.upgradesonly then
			if menu.upgradeplan then
				Helper.closeMenuForSubSection(menu, false, "cArch_upgrade", { menu.component, menu.sequence, menu.stage, {}, menu.upgradeplan, menu.buildlimit, menu.droneplan, math.floor(menu.cost)})
			elseif next(menu.droneplan) then
				Helper.closeMenuForSubSection(menu, false, "cArch_drones", { menu.component, menu.droneplan, math.floor(menu.cost)})
			elseif next(menu.ammoplan) then
				Helper.closeMenuForSubSection(menu, false, "cArch_ammo", { menu.component, menu.ammoplan, math.floor(menu.cost)})
			end
		elseif menu.targethullfraction then
			Helper.closeMenuForSubSection(menu, false, "cArch_repair", { menu.component, menu.sequence, menu.stage, menu.targethullfraction, menu.buildlimit, math.floor(menu.cost) })
		else
			Helper.closeMenuForSection(menu, false, "cArch_buildstation", { menu.macro, success, menu.buildplan, menu.upgradeplan, menu.droneplan, math.floor(menu.cost) })
		end
	else
		if menu.upgradesonly then
			if menu.upgradeplan then
				Helper.closeMenuForSubSection(menu, false, "cArch_upgrade", { menu.component, menu.sequence, menu.stage, {}, menu.upgradeplan, menu.buildlimit})
			elseif next(menu.droneplan) then
				Helper.closeMenuForSubSection(menu, false, "cArch_drones", { menu.component, menu.droneplan})
			elseif next(menu.ammoplan) then
				Helper.closeMenuForSubSection(menu, false, "cArch_ammo", { menu.component, menu.ammoplan})
			end
		elseif menu.targethullfraction then
			Helper.closeMenuForSubSection(menu, false, "cArch_repair", { menu.component, menu.sequence, menu.stage, menu.targethullfraction, menu.buildlimit })
		elseif menu.sequence == "" and menu.stage == 0 then
			Helper.closeMenuForSection(menu, false, "cArch_buildermacrosResult", { menu.macro, menu.buildplan, menu.upgradeplan })
		else
			Helper.closeMenuForSection(menu, false, "cArch_buildtreeResult", { menu.buildplan, menu.upgradeplan })
		end
	end
	menu.cleanup()
end

function menu.buttonEncyclopedia(ware)
	local version = tonumber(string.sub(GetVersionString(), 7, 12))
	if version < 208022 then -- compensate for gEncyclopedia_ware parameter change
		Helper.closeMenuForSubSection(menu, false, "gEncyclopedia_ware", { 0, 0, ware })
	else
		Helper.closeMenuForSubSection(menu, false, "gEncyclopedia_ware", { 0, 0, "wares", ware })
	end
	menu.cleanup()
end

function menu.onShowMenu()
	menu.architect = menu.param[3]
	menu.buildership = menu.param[4]
	menu.component = menu.param[5]
	menu.macro = menu.param[6]
	if menu.macro == GetPlayerPrimaryShipMacro() then
		DebugError("IMPORTANT - Tell Florian immediately. menu_buildcost.lua was called with the playership, should not happen. BuildModule: " .. GetComponentData(menu.buildership, "name"))
	end
	menu.sequence = menu.param[7]
	menu.stage = menu.param[8]
	menu.upgradeplan = menu.param[9]
	menu.buildlimit = menu.param[10] ~= 0
	menu.targethullfraction = menu.param[11] ~= 0 and menu.param[11] or nil
	menu.upgradesonly = menu.param[12] ~= 0 and menu.param[12] or false
	menu.droneplan = menu.param[13] or {}
	menu.ammoplan = menu.param[14] or {}
	menu.recycledship = menu.component or nil
	menu.handlingcharge = 10
	if menu.sequence == nil then
		menu.current = true
		menu.sequence, menu.stage, _, menu.upgradeplan = GetCurrentBuildSlot(menu.component)
	end

	menu.shipbuilding = false
	if GetComponentData(menu.architect, "typestring") == "shiptrader" then
		menu.shipbuilding = true
	end

	if menu.recycledship then
		menu.remotelog("shiprecycle_menu_cost Recycling - " .. GetComponentData(menu.recycledship, "name"))
	end

	local playerMoney = GetPlayerMoney()

	local title = string.format(ReadText(360001, 30), (menu.component and GetComponentData(menu.component, "name") or GetMacroData(menu.macro, "name"))) 

	local setup = Helper.createTableSetup(menu)
	local name, typestring, typeicon, typename, ownericon = GetComponentData(menu.architect, "name", "typestring", "typeicon", "typename", "ownericon")
	setup:addTitleRow({
		Helper.createIcon(typeicon, false, 255, 255, 255, 100, 0, 0, Helper.headerCharacterIconSize, Helper.headerCharacterIconSize),
		Helper.createFontString(typename .. " " .. name, false, "left", 255, 255, 255, 100, Helper.headerRow1Font, Helper.headerRow1FontSize),
		Helper.createIcon(ownericon, false, 255, 255, 255, 100, 0, 0, Helper.headerCharacterIconSize, Helper.headerCharacterIconSize)	-- text depends on selection
	}, nil, {2, 4, 1})
	setup:addTitleRow({ 
		Helper.createFontString(title, false, "left", 129, 160, 182, 100, Helper.headerRow2Font, Helper.headerRow2FontSize, false, Helper.headerRow2Offsetx, Helper.headerRow2Offsety, Helper.headerRow2Height, Helper.headerRow1Width)	-- text depends on selection
	}, nil , {7})

	setup:addHeaderRow({ 
		Helper.getEmptyCellDescriptor(),
		ReadText(1001, 2809),
		ReadText(1001, 1400),
		menu.current and ReadText(1001, 3603) or ReadText(1001, 3605),
		menu.current and ReadText(1001, 3604) or (menu.shipbuilding and ReadText(1001, 2808) or ReadText(1001, 3601))
	}, nil, {1, 2, 1, 1, 2})

	menu.buildplan = {
		{ menu.sequence, menu.stage }
	} 
	menu.cost = 0

	local resources
	if menu.current then
		resources = GetCurrentBuildSlotResources(menu.buildership)
	elseif menu.targethullfraction then
		resources = GetRepairResources(menu.buildership, menu.component, menu.sequence, menu.stage, menu.buildlimit, menu.targethullfraction)
	else
		if menu.upgradeplan then
			if menu.upgradesonly then
				resources = GetUpgradesResources(menu.buildership, menu.component, menu.sequence, menu.stage, menu.buildlimit, menu.upgradeplan)
			else
				resources = GetBuildSlotResources(menu.buildership, menu.macro, menu.sequence, menu.stage, menu.upgradeplan)
			end
		else
			if next(menu.droneplan) or next(menu.ammoplan) then
				resources = {}
			else
				resources = GetBuildSlotResources(menu.buildership, menu.macro, menu.sequence, menu.stage)
			end
		end
	end
	if next(resources) then
		table.sort(resources, function (a, b) return a.cycle > b.cycle end)
	end

	menu.neededresources = GetNeededBuildSlotResources(menu.buildership)

	local cargo = GetComponentData(GetContextByClass(menu.buildership, "container", true), "cargo")
	
	menu.hasentries = false
	menu.recyclewares = {}
	menu.recyclewaresextra = {}
	local hullfraction = tonumber(GetComponentData(menu.recycledship, "hullpercent") / 100)
	--menu.remotelog("Hull fraction is " .. tostring(hullfraction))
	
	local recyclingIssues = ReadText(1001, 1604) .. " - " -- "Not enough resources - "
	local lengthrecyclingIssues = #recyclingIssues
	menu.recyclingPrereqsMet = true -- only allow recycling if required resources present

	for _, entry in ipairs(resources) do
		if entry.cycle > 0 then
			local icon, component = GetWareData(entry.ware, "icon", "component")
			local price = entry.price + (menu.shipbuilding and entry.price or 0)
			if menu.recycledship then -- get paid for recycled wares
				-- menu.remotelog("ware: " .. tostring(entry.ware))
				if entry.ware ~= "energycells" and entry.ware ~= "foodrations" then
					if string.find(tostring(entry.ware), "turret") or string.find(tostring(entry.ware), "shieldgenerator") then
						-- menu.remotelog("external")
						table.insert(menu.recyclewares, {entry.ware, entry.cycle})
						entry.cycle = entry.cycle * -1 -- ship external objects 100% recycling
						price = price * -0.93 -- fudge factor
					else
						entry.cycle = math.ceil(entry.cycle * -1 * hullfraction) 
						table.insert(menu.recyclewares, {entry.ware, math.ceil((entry.cycle * -1 * 0.9) + 0.49)}) -- set 90% recycling rate
						price = price * -0.8 -- reduce price of recycled wares by 20%
					end
				else
					-- entry.cycle = entry.cycle * 100 -- testing
					if entry.ware == "energycells" then 
						menu.energycells = entry.cycle 
					end
					if entry.ware == "foodrations" then 
						menu.foodrations = entry.cycle 
					end
					if cargo[entry.ware] == nil or cargo[entry.ware] < entry.cycle then
						recyclingIssues = recyclingIssues .. " " .. entry.name .. " "
						menu.recyclingPrereqsMet = false
					end
				end
			end
			local color = menu.white
			if (not menu.current) and menu.shipbuilding and ((cargo[entry.ware] or 0) < entry.cycle) then
				color = menu.red
			end
			setup:addSimpleRow({ 
				Helper.createButton(nil, Helper.createButtonIcon(icon, nil, 255, 255, 255, 100), false, true, 0, 0),
				Helper.createFontString(entry.name, false, "left", color.r, color.g, color.b, color.a),
				Helper.createFontString(ConvertIntegerString(cargo[entry.ware] or 0, true, 0, true), false, "right", color.r, color.g, color.b, color.a),
				Helper.createFontString(ConvertIntegerString(entry.cycle, true, 0, true), false, "right", color.r, color.g, color.b, color.a),
				Helper.createFontString(menu.current and ConvertIntegerString(menu.getNeededResourceAmount(entry.ware), true, 0, false) or ConvertMoneyString(price, false, true, 5, true) .. " " .. ReadText(1001, 101), false, "right", color.r, color.g, color.b, color.a)
			}, nil, {1, 2, 1, 1, 2})
			AddKnownItem("wares", entry.ware)
			menu.hasentries = true
			if not menu.current then
				if entry.ware ~= "energycells" and entry.ware ~= "foodrations" then -- skip as recycling uses these
					menu.cost = menu.cost + price
				end
			end
		end
	end
	
	local droneheader = false
	if next(menu.droneplan) then
		for _, entry in ipairs(menu.droneplan) do
			if entry[2] ~= 0 then
				if not droneheader then -- add in Drones title row 
					setup:addHeaderRow({ 
						Helper.getEmptyCellDescriptor(),
						ReadText(1001, 8)
					}, nil, {1, 2, 1, 1, 2})
					droneheader = true
				end
				local name = GetWareData(entry[3], "name")
				name = name .. " \27Y " .. ReadText(360001, 100) .. menu.handlingcharge .. "% " .. ReadText(1002, 12210) .. "\27X" --  - __% Discount
				local price
				if menu.recycledship then -- recycle drones quantities are negative
					entry[2] = math.abs(entry[2]) -- force +ve
					table.insert(menu.recyclewaresextra, {entry[3], entry[2]})
					entry[2] = entry[2] * -1
				end
				if (entry[2] < 0) and not menu.recycledship then
					price = entry[2] * GetContainerWarePrice(menu.buildership, entry[3], true) * 0.80
				else
					price = entry[2] * GetContainerWarePrice(menu.buildership, entry[3], false) * 0.85 * ((100 - menu.handlingcharge) / 100)
				end
				local color = menu.white
				if (not menu.current) and menu.shipbuilding and ((cargo[entry[3]] or 0) < entry[2]) then
					color = menu.red
				end
				setup:addSimpleRow({ 
					Helper.createButton(nil, Helper.createButtonIcon(GetWareData(entry[3], "icon"), nil, 255, 255, 255, 100), false, true, 0, 0),
					Helper.createFontString(name, false, "left", color.r, color.g, color.b, color.a),
					Helper.createFontString(ConvertIntegerString(cargo[entry[3]] or 0, true, 0, true), false, "right", color.r, color.g, color.b, color.a),
					Helper.createFontString(ConvertIntegerString(entry[2], true, 0, true), false, "right", color.r, color.g, color.b, color.a),
					Helper.createFontString(ConvertMoneyString(price, false, true, 5, true) .. " " .. ReadText(1001, 101), false, "right", color.r, color.g, color.b, color.a)
				}, nil, {1, 2, 1, 1, 2})
				AddKnownItem("wares", entry[3])
				menu.hasentries = true
				menu.cost = menu.cost + price
			end
		end
	end

	if #menu.ammoplan > 0 then -- add in Ammunition title row
		setup:addHeaderRow({ 
			Helper.getEmptyCellDescriptor(),
			ReadText(1001, 2800)
			}, nil, {1, 2, 1, 1, 2})
	end

	if next(menu.ammoplan) then
		for _, entry in ipairs(menu.ammoplan) do
			if entry[2] ~= 0 then
				local name = GetWareData(entry[3], "name")
				name = name .. " \27Y " .. ReadText(360001, 100) .. menu.handlingcharge .. "% " .. ReadText(1002, 12210) .. "\27X" --  - __% Discount
				local price
				if menu.recycledship then -- recycle ammo quantities are negative
					entry[2] = math.abs(entry[2]) -- force +ve
					table.insert(menu.recyclewaresextra, {entry[3], entry[2]})
					entry[2] = entry[2] * -1
				end
				if entry[2] < 0 then
					price = entry[2] * GetContainerWarePrice(menu.buildership, entry[3], true) * 0.80
				else
					price = entry[2] * GetContainerWarePrice(menu.buildership, entry[3], false) * 0.9 * ((100 - menu.handlingcharge) / 100)
				end
				local color = menu.white
				if (not menu.current) and menu.shipbuilding and ((cargo[entry[3]] or 0) < entry[2]) then
					color = menu.red
				end
				setup:addSimpleRow({ 
					Helper.createButton(nil, Helper.createButtonIcon(GetWareData(entry[3], "icon"), nil, 255, 255, 255, 100), false, true, 0, 0),
					Helper.createFontString(name, false, "left", color.r, color.g, color.b, color.a),
					Helper.createFontString(ConvertIntegerString(cargo[entry[3]] or 0, true, 0, true), false, "right", color.r, color.g, color.b, color.a),
					Helper.createFontString(ConvertIntegerString(entry[2], true, 0, true), false, "right", color.r, color.g, color.b, color.a),
					Helper.createFontString(ConvertMoneyString(price, false, true, 5, true) .. " " .. ReadText(1001, 101), false, "right", color.r, color.g, color.b, color.a)
				}, nil, {1, 2, 1, 1, 2})
				AddKnownItem("wares", entry[3])
				menu.hasentries = true
				menu.cost = menu.cost + price
			end
		end
	end

	local shipcargo = GetComponentData(menu.component, "cargo")
	local shipcargocount = 0
	for ware, cycle in pairs(shipcargo) do -- count the ship cargo manually as lua won't properly
		shipcargocount = shipcargocount + 1
		--menu.remotelog("shipcargo is " .. tostring(ware) .. " " .. tostring(cycle))
	end
	--menu.remotelog("shipcargo items " .. shipcargocount)
	
	if shipcargocount > 0 then -- add in Cargo title row
		setup:addHeaderRow({ 
			Helper.getEmptyCellDescriptor(),
			ReadText(1001, 63)
			}, nil, {1, 2, 1, 1, 2})
	end

	if next(shipcargo) then
		for ware, cycle in pairs(shipcargo) do
			if cycle > 0 then
				-- cycle = cycle * 10 -- for testing limits
				local icon, component, avgprice = GetWareData(ware, "icon", "component", "avgprice")
				--local price = entry.price + (menu.shipbuilding and entry.price or 0)
				local price
				local sparespace
				local needed
				local waredesc = GetWareData(ware, "name")
				if cargo[ware] then -- station uses this ware
					local warecapacity = GetWareProductionLimit(GetContextByClass(menu.buildership, "container", true), ware)
					sparespace = warecapacity - cargo[ware]
					-- menu.remotelog(ware .. " num " .. cycle .. " capacity is " .. tostring(warecapacity) .. " stock " .. cargo[ware] .. " sparespace " .. sparespace)
					if (sparespace - tonumber(cycle)) >= 0 then -- all fits in station storage
						table.insert(menu.recyclewaresextra, {ware, cycle})
						price = cycle * avgprice * -1 * ((100 - menu.handlingcharge) / 100)
						needed = tostring(cycle * -1)
						waredesc = waredesc .. " \27Y " .. ReadText(360001, 100) .. menu.handlingcharge .. "% " .. ReadText(1002, 12210) .. "\27X" --  - __% Discount
					else -- recycle what fits and discount the rest by 50%
						if sparespace > 0 then
							table.insert(menu.recyclewaresextra, {ware, sparespace})
							waredesc = waredesc .. " \27Y " .. tostring(sparespace).. " -" .. menu.handlingcharge .. "%  " .. ReadText(360001, 50) .. " " .. tostring((sparespace - cycle) * -1) .. " -50%" .. "\27X" -- Excess xxx - 50% Discount
						else -- storage full
							sparespace = 0
							waredesc = waredesc .. " \27Y " .. ReadText(360001, 50) .. " " .. tostring((sparespace - cycle) * -1) .. " -50% " .. ReadText(1002, 12210) .. "\27X" -- Excess xxx - 50% Discount
						end
						price = sparespace * avgprice * -1 * ((100 - menu.handlingcharge) / 100) + (sparespace - cycle) * avgprice * 0.5
						needed = tostring(sparespace * -1)
					end
				else -- station cannot use this ware so discount it by 50%
					price = cycle * avgprice * -0.5
					needed = " \27Y" .. tostring(cycle * -1) .. "\27X" -- in yellow
				end
				cycle = cycle * -1
				
				local color = menu.white
				if (not menu.current) and menu.shipbuilding and ((cargo[ware] or 0) < cycle) then
					color = menu.red
				end

				local stock
				if cargo[ware] then
					stock = ConvertIntegerString(cargo[ware] or "0", true, 0, true)
				else
					waredesc = waredesc .. " \27Y " .. ReadText(360001, 40)  .. "50% " .. ReadText(1002, 12210) .. "\27X" -- Not recyclable - 50% Discount
					stock = " \27Y" .. ReadText(1001, 2672) .. "\27X" -- in yellow
				end
				setup:addSimpleRow({ 
					Helper.createButton(nil, Helper.createButtonIcon(icon, nil, 255, 255, 255, 100), false, true, 0, 0),
					Helper.createFontString(waredesc, false, "left", color.r, color.g, color.b, color.a),
					Helper.createFontString(stock, false, "right", color.r, color.g, color.b, color.a),
					Helper.createFontString(needed, false, "right", color.r, color.g, color.b, color.a),
					Helper.createFontString(menu.current and ConvertIntegerString(menu.getNeededResourceAmount(ware), true, 0, false) or ConvertMoneyString(price, false, true, 5, true) .. " " .. ReadText(1001, 101), false, "right", color.r, color.g, color.b, color.a)
				}, nil, {1, 2, 1, 1, 2})
				AddKnownItem("wares", ware)
				menu.hasentries = true
				if not menu.current then
					menu.cost = menu.cost + price
				end
			end
		end	
	end
	
	local infodesc = setup:createCustomWidthTable({ Helper.scaleX(Helper.standardButtonWidth), Helper.scaleX(Helper.headerCharacterIconSize - Helper.standardButtonWidth) - 5, Helper.scaleX(menu.current and 350 or 400), Helper.scaleX(menu.current and 150 or 100), Helper.scaleX(menu.current and 150 or 100), 0, Helper.scaleX(Helper.headerCharacterIconSize) + 37}, false, true, true, 1, 3, 0, 0, Helper.scaleY(menu.shipbuilding and 415 or 505))
	
	local selectdesc, buttondesc
	if not menu.current then
		setup = Helper.createTableSetup(menu)
		
		local emptyFontStringSmall = Helper.createFontString("", false, Helper.standardHalignment, Helper.standardColor.r, Helper.standardColor.g, Helper.standardColor.b, Helper.standardColor.a, Helper.standardFont, 6, false, Helper.headerRow1Offsetx, Helper.headerRow1Offsety, 6)

		setup:addHeaderRow({ emptyFontStringSmall }, nil, {4})
		setup:addTitleRow({ 
			Helper.getEmptyCellDescriptor(),
			Helper.createFontString((menu.shipbuilding and ReadText(1001, 2927) or ReadText(1001, 3602)), false, "left", 255, 255, 255, 100, Helper.standardFontBold),
			Helper.getEmptyCellDescriptor(),
			Helper.createFontString(ConvertMoneyString(menu.cost, false, true, 5, true) .. " " .. ReadText(1001, 101), false, "right", 255, 255, 255, 100, Helper.standardFontBold)
		}, nil, nil, nil, Helper.defaultSimpleBackgroundColor)
		if menu.shipbuilding then
			setup:addHeaderRow({ emptyFontStringSmall }, nil, {4})

			setup:addTitleRow({ 
				Helper.getEmptyCellDescriptor(), 
				ReadText(1001, 2003), 
				Helper.getEmptyCellDescriptor(), 
				Helper.createFontString(ConvertMoneyString(playerMoney, false, true, 5, true) .. " " .. ReadText(1001, 101), false, "right")
			}, nil, nil, nil, Helper.defaultSimpleBackgroundColor)

			local factionstring = "      " .. ReadText(1001, 3) .. " " .. ReadText(1001, 43) .. ReadText(1001, 120) .. " " .. GetComponentData(menu.architect, "ownername") -- Station Faction: .... 
			if GetComponentData(menu.architect, "owner") == "player" then -- don't pay if player shipyard
				menu.cost = 0
			end
			local color = menu.white
			if -math.floor(menu.cost) < 0 then
				color = menu.red
			else
				color = menu.green
			end
			setup:addTitleRow({ 
				Helper.getEmptyCellDescriptor(), 
				ReadText(1001, 2005)..factionstring, 
				Helper.getEmptyCellDescriptor(), 
				Helper.createFontString(ConvertMoneyString(-math.floor(menu.cost), false, true, 5, true) .. " " .. ReadText(1001, 101), false, "right", color.r, color.g, color.b, color.a)
			}, nil, nil, nil, Helper.defaultSimpleBackgroundColor)

			if (playerMoney - math.floor(menu.cost)) < 0 then
				color = menu.red
			else
				color = menu.white
			end
			setup:addTitleRow({ 
				Helper.getEmptyCellDescriptor(), 
				ReadText(1001, 2004), 
				Helper.getEmptyCellDescriptor(), 
				Helper.createFontString(ConvertMoneyString(playerMoney - math.floor(menu.cost), false, true, 5, true) .. " " .. ReadText(1001, 101), false, "right", color.r, color.g, color.b, color.a)
			}, nil, nil, nil, Helper.defaultSimpleBackgroundColor)
		end

		selectdesc = setup:createCustomWidthTable({Helper.standardButtonWidth, 500 + Helper.headerCharacterIconSize - Helper.standardButtonWidth, 100, 0}, false, false, true, 0, 0, 0, menu.shipbuilding and 395 or 485)

		if not menu.recyclingPrereqsMet then
			menu.remotelog("recyclingPrereqsMet failed " .. recyclingIssues)
		end
		
		setup = Helper.createTableSetup(menu)
		menu.isokbuttonenabled = menu.hasentries and (not menu.shipbuilding or playerMoney >= math.floor(menu.cost)) and (menu.recycledship and menu.recyclingPrereqsMet)
		setup:addSimpleRow({ 
			Helper.getEmptyCellDescriptor(),
			Helper.createButton(Helper.createButtonText(ReadText(1001, 2669), "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_B", true)),
			Helper.getEmptyCellDescriptor(),
			Helper.getEmptyCellDescriptor(),
			Helper.getEmptyCellDescriptor(),
			Helper.getEmptyCellDescriptor(),
			Helper.getEmptyCellDescriptor(),
			Helper.createButton(Helper.createButtonText(ReadText(1001, 14), "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, menu.isokbuttonenabled, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_A", true)),
			Helper.getEmptyCellDescriptor()
		})
		buttondesc = setup:createCustomWidthTable({48, 150, 48, 150, 0, 150, 48, 150, 48}, false, false, false, 2, 1, 0, 550)
	end

	-- create tableview
	if menu.current then
		menu.infotable = Helper.displayTableView(menu, infodesc, false)
	else
		menu.infotable, menu.selecttable, menu.buttontable = Helper.displayThreeTableView(menu, infodesc, selectdesc, buttondesc, false)
	end

	local units = GetUnitStorageData(GetContextByClass(menu.buildership, "container", true), "welder")
	for _, entry in ipairs(units) do
		if entry.macro == "units_size_xs_welder_drone_macro" then
			--menu.remotelog("Construction drone(s) " .. entry.amount)
			if entry.amount < 5 then
				recyclingIssues = recyclingIssues .. " " .. GetMacroData("units_size_xs_welder_drone_macro", "name") .. " < 5 "
				menu.recyclingPrereqsMet = false
			end
		end
	end
	
	if lengthrecyclingIssues ~= #recyclingIssues then -- there are some issues
		local infotext = "%s"
		Helper.updateCellText(menu.infotable, 2, 1, string.format(infotext, " \27R" .. recyclingIssues .. "\27X"))
	end

	-- set button scripts
	local nooflines = 4
	for i, entry in ipairs(resources) do
		if (entry.cycle > 0) or menu.recycledship then
			Helper.setButtonScript(menu, nil, menu.infotable, nooflines, 1, function () return menu.buttonEncyclopedia(entry.ware) end)
			nooflines = nooflines + 1
		end
	end
	if next(menu.droneplan) then
		if droneheader then
			nooflines = nooflines + 1
		end
		for i, entry in ipairs(menu.droneplan) do
			if entry[2] ~= 0 then
				Helper.setButtonScript(menu, nil, menu.infotable, nooflines, 1, function () return menu.buttonEncyclopedia(entry[3]) end)
				nooflines = nooflines + 1
			end
		end
	end
	if next(menu.ammoplan) then
		if #menu.ammoplan > 0 then
			nooflines = nooflines + 1
		end
		for i, entry in ipairs(menu.ammoplan) do
			if entry[2] ~= 0 then
				Helper.setButtonScript(menu, nil, menu.infotable, nooflines, 1, function () return menu.buttonEncyclopedia(entry[3]) end)
				nooflines = nooflines + 1
			end
		end
	end
	if next(shipcargo) then
		if shipcargocount > 0 then
			nooflines = nooflines + 1
		end
		for ware, cycle in pairs(shipcargo) do
			if cycle ~= 0 then
				Helper.setButtonScript(menu, nil, menu.infotable, nooflines, 1, function () return menu.buttonEncyclopedia(ware) end)
				nooflines = nooflines + 1
			end
		end
	end
	if not menu.current then
		Helper.setButtonScript(menu, nil, menu.buttontable, 1, 2, function () return menu.onCloseElement("back") end)
		Helper.setButtonScript(menu, nil, menu.buttontable, 1, 8, menu.buttonOK)
	end

	-- clear descriptors again
	Helper.releaseDescriptors()
end

menu.updateInterval = 1.0

function menu.onUpdate()
	local currentplayermoney = GetPlayerMoney()
	if not menu.current then
		if menu.shipbuilding then
			Helper.updateCellText(menu.selecttable, 4, 4, ConvertMoneyString(currentplayermoney, false, true, 5, true) .. " " .. ReadText(1001, 101))
			local color
			if (currentplayermoney - math.floor(menu.cost)) < 0 then
				color = menu.red
			else
				color = menu.white
			end
			Helper.updateCellText(menu.selecttable, 6, 4, ConvertMoneyString(currentplayermoney - math.floor(menu.cost), false, true, 5, true) .. " " .. ReadText(1001, 101), color)
		end
		if menu.hasentries then
			local isokbuttonenabled = menu.recycledship and menu.recyclingPrereqsMet
			if menu.isokbuttonenabled ~= isokbuttonenabled then
				menu.isokbuttonenabled = isokbuttonenabled
				Helper.removeButtonScripts(menu, menu.buttontable, 1, 8)
				SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(ReadText(1001, 14), "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, menu.isokbuttonenabled, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_A", true)), 1, 8)
				Helper.setButtonScript(menu, nil, menu.buttontable, 1, 8, menu.buttonOK)
			end
		end
	end
end

function menu.onRowChanged(row, rowdata)
end

function menu.onSelectElement()
end

function menu.onCloseElement(dueToClose)
	if dueToClose == "close" then
		Helper.closeMenuAndCancel(menu)
		menu.cleanup()
	else
		Helper.closeMenuAndReturn(menu)
		menu.cleanup()
	end
end

function menu.getNeededResourceAmount(resource)
	for _, neededresource in ipairs(menu.neededresources) do
		if resource == neededresource.ware then
			return neededresource.cycle
		end
	end
	return 0
end

function menu.remotelog(s)
--	DebugError("remotelog " .. GetVersionString() .. " " .. tostring(s))
	local version = tonumber(string.sub(GetVersionString(), string.find(GetVersionString(), '(',1,true) + 1, string.find(GetVersionString(), '(',1,true) + 6)) or 208022
--	DebugError("remotelog " .. tostring(version) .. " " .. tostring(s))
	if version < 208022 then -- compensate for AddUITriggeredEvent parameter change
		AddUITriggeredEvent("St_Prod_Logger", s)
	else
		AddUITriggeredEvent("St_Prod_Logger", "", s)
	end
end

init()

-- section == gMainInfo_property
-- param == { 0, 0, faction [, mode, modeparam] }

-- modes: - "sellship", param: { returnsection, buildmodule_or_container }
--        - "recycleship", param: { Sell_returnsection, buildmodule_or_container, Recycle_returnsection, dock_size }
--		  - "selectobject", param: { returnsection, refcomponent, nil, nil, potentialsubordinate, disablestations, disablecapships, disablesmallships, canhavedrones, nosubordinate, noorder, haspilot, hascargocapacity, checkforbuildmodule, hasbuildingmodule, hascontrolentity, allowbuildingmodules }

local menu = {
	name = "ShipRecycle_PropertyMenu",
	transparent = { r = 0, g = 0, b = 0, a = 0 },
	extendedcategories = { ships = true, stations = true }
}

local function init()
	Menus = Menus or { }
	table.insert(Menus, menu)
	if Helper then
		Helper.registerMenu(menu)
	end
end

function menu.cleanup()
	UnregisterAddonBindings("ego_detailmonitor")

	menu.title = nil
	menu.mode = nil
	menu.realmode = nil
	menu.modeparam = {}
	menu.ships = {}
	menu.stations = {}
	menu.drones = {}
	menu.faction = nil
	menu.playership = nil
	menu.lastupdate = nil
	menu.subordinates = {}
	menu.autopilottarget = nil
	menu.maxtrips = nil

	menu.rawdronewares = {}
	menu.droneplan = {}
	menu.infotable = nil
	menu.selecttable = nil
end

-- Menu member functions

function menu.buttonComm()
	local entities = Helper.getSuitableControlEntities(menu.rowDataMap[Helper.currentDefaultTableRow], true)
	if #entities == 1 then
		Helper.closeMenuForSubConversation(menu, false, "default", entities[1], nil, "facecopilot")
	else
		Helper.closeMenuForSubSection(menu, false, "gMain_propertyResult", menu.rowDataMap[Helper.currentDefaultTableRow])
	end
	menu.cleanup()
end

function menu.buttonBroadcast()
	Helper.closeMenuForSubSection(menu, false, "gOrders_broadcast_main")
	menu.cleanup()
end

function menu.buttonShowMap()
	Helper.closeMenuForSubSection(menu, false, "gMainNav_menumap", { 0, 0, "zone", GetContextByClass(menu.rowDataMap[Helper.currentDefaultTableRow], "zone", true), nil, menu.rowDataMap[Helper.currentDefaultTableRow] })
	menu.cleanup()
end

function menu.buttonDetails()
	local component = menu.rowDataMap[Helper.currentDefaultTableRow]
	if menu.mode == "selectobject" then
		Helper.closeMenuForSubSection(menu, false, menu.modeparam[1], { 0, 0, component })
		menu.cleanup()
	elseif menu.mode == "sellship" then
		local totalprice = GetTotalValue(component, true, GetContextByClass(menu.modeparam[2], "container"))

		Helper.closeMenuForSubSection(menu, false, menu.modeparam[1], { component, math.ceil(totalprice) })
		menu.cleanup()
	else
		Helper.closeMenuForSubSection(menu, false, "gMain_object", { 0, 0, component })
		menu.cleanup()
	end
end

function menu.buttonRecycle()
	local component = menu.rowDataMap[Helper.currentDefaultTableRow]
	if menu.realmode == "recycleship" then
		local totalprice = GetTotalValue(component, true, GetContextByClass(menu.modeparam[2], "container"))
					
		local upgrades = GetAllUpgrades(component) -- get upgrades (turrets and shields)
		local upgradeplan = {}
		for ut, upgrade in Helper.orderedPairs(upgrades) do
			if not (ut == "totaltotal" or ut == "totalfree" or ut == "totaloperational" or ut == "totalconstruction" or ut == "estimated") then
				if upgrade.total ~= 0 then
					table.insert(upgradeplan, { ut, upgrade.operational / upgrade.total })
				end
			end
		end

		local dronewares = {}
		for _, ware in ipairs(menu.rawdronewares) do -- get drones
			table.insert(dronewares, ware)
		end
		
		local macro 
		if component then -- add in available ship drones
			macro = GetComponentData(component, "macro")

			local transportdronemacros = GetTransportUnitMacros(macro)
			for i, k in ipairs(transportdronemacros) do
				table.insert(dronewares, GetMacroData(k, "ware"))
			end

			local miningdronemacros = GetMiningUnitMacros(macro)
			for i, k in ipairs(miningdronemacros) do
				table.insert(dronewares, GetMacroData(k, "ware"))
			end
		end

		local droneplan = {} -- create a droneplan
		local units = GetUnitStorageData(component)
		for _, ware in ipairs(dronewares) do
			for _, entry in ipairs(units) do
				if entry.macro == GetWareData(ware, "component") then
					table.insert(droneplan, { entry.macro, entry.amount, ware })
					break
				end
			end
		end

		Helper.closeMenuForSubSection(menu, false, menu.modeparam[3], { 0, 0, menu.param[5][6], menu.param[5][2], component, GetComponentData(component, "macro"), "", 0, upgradeplan, 1, nil, 0, droneplan } )
		--DebugError("Recycle - "..GetComponentData(component, "name"))
		menu.cleanup()
	end
end

function menu.buttonExtend(component, row)
	if menu.extendedcategories[tostring(component)] then
		menu.extendedcategories[tostring(component)] = nil
	else
		menu.extendedcategories[tostring(component)] = true
	end
	
	menu.toprow = GetTopRow(menu.selecttable)
	menu.selectrow = row
	menu.display(false)
end

function menu.hotkey(action)
	if action == "INPUT_ACTION_ADDON_DETAILMONITOR_A_SHIFT" then
		if menu.rowDataMap[Helper.currentDefaultTableRow] then
			local component = menu.rowDataMap[Helper.currentDefaultTableRow]
			if IsSameComponent(menu.autopilottarget, component) then
				StopAutoPilot()
			else
				StartAutoPilot(component)
			end

			menu.toprow = GetTopRow(menu.selecttable)
			menu.selectrow = Helper.currentDefaultTableRow
			menu.display(false)
		end
	end
end

function menu.onShowMenu()
	-- DebugError("onShowMenu menu.faction "..menu.param[3].." menu.mode "..menu.param[4])
	menu.faction = menu.param[3]
	menu.mode = menu.param[4]
	menu.realmode = menu.param[4]
	menu.modeparam = menu.param[5] or {}
	menu.rawdronewares = menu.modeparam[5] or {}
	menu.title = ReadText(1001, 1000)
	if menu.realmode == "recycleship" then -- piggyback onto sellship
		menu.title = ReadText(360001, 1)
		menu.mode = "sellship"
	end
	if menu.faction ~= "player" then
		menu.title = menu.title .. " (" .. menu.faction .. ")" 
	end
	menu.playership = GetPlayerPrimaryShipID()

	menu.maxtrips = 3
	if PlayerPrimaryShipHasContents("trademk2") then
		menu.maxtrips = 5
	elseif PlayerPrimaryShipHasContents("trademk3") then
		menu.maxtrips = 7
	end

	RegisterAddonBindings("ego_detailmonitor")
	Helper.setKeyBinding(menu, menu.hotkey)

	menu.display(true)
end

function menu.display(firsttime)
	menu.lastupdate = GetCurTime()

	Helper.removeAllButtonScripts(menu)
	Helper.currentTableRow = {}
	Helper.currentTableRowData = nil
	menu.rowDataMap = {}

	menu.autopilottarget = GetAutoPilotTarget()

	local setup = Helper.createTableSetup(menu)
	setup:addTitleRow({
		Helper.createFontString(menu.title, false, "left", 255, 255, 255, 100, Helper.headerRow1Font, Helper.headerRow1FontSize, false, Helper.headerRow1Offsetx, Helper.headerRow1Offsety, Helper.headerRow1Height, Helper.headerRow1Width)
	})
	setup:addTitleRow({ 
		Helper.createFontString("", false, "left", 129, 160, 182, 100, Helper.headerRow2Font, Helper.headerRow2FontSize, true, Helper.headerRow2Offsetx, Helper.headerRow2Offsety, 2 * Helper.headerRow2Height, Helper.headerRow1Width)	-- text depends on selection
	})
	local infodesc = setup:createCustomWidthTable({0}, false)

	menu.stations = GetContainedStationsByOwner(menu.faction)
	menu.ships = GetContainedShipsByOwner(menu.faction)
	menu.drones = { }
	for i = #menu.ships, 1, -1 do
		local commander = GetCommander(menu.ships[i])
		if commander then
			table.remove(menu.ships, i)
		elseif IsSameComponent(menu.ships[i], menu.playership) then
			table.remove(menu.ships, i)
		elseif menu.mode == "sellship" and (not GetComponentData(menu.ships[i], "issellable")) then
			table.remove(menu.ships, i)
		elseif IsComponentClass(menu.ships[i], "drone") then
			local dronecommander = GetDroneCommander(menu.ships[i])
			if not IsSameComponent(dronecommander, menu.playership) then
				table.insert(menu.drones, 1, menu.ships[i])
			end
			table.remove(menu.ships, i)
		end
	end
	menu.subordinates = {}

	setup = Helper.createTableSetup(menu)
	if menu.mode ~= "sellship" then
		menu.createSection(setup, "stations", ReadText(1001, 4), menu.stations, "-- " .. ReadText(1001, 33) .. " --", true)
	end
	menu.createSection(setup, "ships",    ReadText(1001, 6),    menu.ships,    "-- " .. ReadText(1001, 34) .. " --", true)
	setup:addFillRows(15, nil, {5})

	local selectdesc = setup:createCustomWidthTable({Helper.standardButtonWidth, 0, 170, 220 - Helper.standardTextHeight - 5, Helper.standardTextHeight}, false, false, true, 1, 0, 0, Helper.tableOffsety + Helper.headerRow2Height, 460, false, menu.toprow, menu.selectrow)
	menu.toprow = nil
	menu.selectrow = nil

	-- button table
	setup = Helper.createTableSetup(menu)
	setup:addSimpleRow({ 
		Helper.getEmptyCellDescriptor(),
		Helper.createButton(Helper.createButtonText(ReadText(1001, 2669), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, true, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_B", true)),
		Helper.getEmptyCellDescriptor(),
		Helper.createButton(Helper.createButtonText(ReadText(1001, 3408), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, not menu.mode, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_BACK", true)),
		Helper.getEmptyCellDescriptor(),
		Helper.createButton(Helper.createButtonText(ReadText(1001, 3216), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, not menu.mode, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_Y", true)),
		Helper.getEmptyCellDescriptor(),
		Helper.createButton(Helper.createButtonText(menu.mode and ReadText(1001, 3102) or ReadText(1001, 2961), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, true, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_X", true)),
		Helper.getEmptyCellDescriptor()
	}, nil, nil, false, menu.transparent)
	local buttondesc = setup:createCustomWidthTable({48, 150, 48, 150, 0, 150, 48, 150, 48}, false, false, true, 2, 1, 0, 555, 0, false)

	-- create tableview
	menu.infotable, menu.selecttable, menu.buttontable = Helper.displayThreeTableView(menu, infodesc, selectdesc, buttondesc, false, "", "", 0, 0, 0, 0, "both", firsttime)

	local offsetrow = 1
	if menu.mode ~= "sellship" then
		offsetrow = menu.setButtonsForSection("stations", menu.stations, offsetrow)
	end
	if menu.tripheader then
		Helper.updateCellText(menu.selecttable, offsetrow, 2, ReadText(1001, 6) .. " (" .. ReadText(1001, 2937) .. ")")
		menu.tripheader = nil
	end
	offsetrow = menu.setButtonsForSection("ships", menu.ships, offsetrow)

	Helper.setButtonScript(menu, nil, menu.buttontable, 1, 2, function () return menu.onCloseElement("back") end)
	Helper.setButtonScript(menu, nil, menu.buttontable, 1, 4, menu.buttonShowMap)
	Helper.setButtonScript(menu, nil, menu.buttontable, 1, 6, menu.buttonComm)
	Helper.setButtonScript(menu, nil, menu.buttontable, 1, 8, menu.buttonDetails)

	-- clear descriptors again
	Helper.releaseDescriptors()
end

menu.updateInterval = 10.0

function menu.onUpdate()
	if menu.lastupdate + 60 < GetCurTime() then
		menu.toprow = GetTopRow(menu.selecttable)
		menu.selectrow = Helper.currentDefaultTableRow
		menu.display(false)
	end
end

function menu.onRowChanged(row, rowdata)
	if menu.rowDataMap[Helper.currentDefaultTableRow] then
		rowdata = menu.rowDataMap[Helper.currentDefaultTableRow]

		-- [paramoffset],  'cArch_sellshipselected', $BuildModule, 'cArch_recycleshipselected',[$BuildModule.dockslot.component.docksize]
		local buildmodule = GetComponentData(menu.modeparam[2], "name")
		-- DebugError("onRowChanged BuildModule "..buildmodule)
		local fitsindock = false
		local docksizes = menu.modeparam[4] or {}
		for key,value in ipairs(docksizes) 
		do
			local shipsize = string.gsub(value,"dock","ship")
			if IsComponentClass(rowdata, shipsize) then
				fitsindock = true
			end
		end	
		--DebugError("onRowChanged "..GetComponentData(rowdata, "name").." fits in dock - "..tostring(fitsindock))
		
		local hascontrolentity = #Helper.getSuitableControlEntities(rowdata) > 0
		local shieldpercent, hullpercent, cluster, sector, zone = GetComponentData(rowdata, "shieldpercent", "hullpercent", "cluster", "sector", "zone")
		local aicommand
		if IsComponentClass(rowdata, "station") then
			local tradenpc = GetComponentData(rowdata, "tradenpc")
			if tradenpc then
				aicommand = Helper.parseAICommand(tradenpc)
			else
				aicommand = "-"
			end
		else
			local pilot = GetComponentData(rowdata, "pilot")
			if pilot then
				aicommand = Helper.parseAICommand(pilot)
			else
				aicommand = "-"
			end
		end
		local infotext = IsSameComponent(rowdata, menu.playership) and "%s = %d %%, %s = %d %%, %s = %s / %s / %s" or "%s = %d %%, %s = %d %%, %s = %s / %s / %s\n%s%s %s"
		Helper.updateCellText(menu.infotable, 2, 1, string.format(infotext, ReadText(1001, 2), shieldpercent, ReadText(1001, 1), hullpercent, ReadText(1001, 2943), cluster, sector, zone, ReadText(1001, 78), ReadText(1001, 120), aicommand))
		if not fitsindock and not IsSameComponent(rowdata, menu.playership) then
			Helper.updateCellText(menu.infotable, 2, 1, string.format(infotext, ReadText(1001, 2), shieldpercent, ReadText(1001, 1), hullpercent, ReadText(1001, 2943), cluster, sector, zone, ReadText(1001, 78), ReadText(1001, 120), aicommand) .. " \27R" .. ReadText(360001, 10) .. GetComponentData(menu.modeparam[2], "name") .. "\27X")
		end
		--- SHOW ON MAP
		Helper.removeButtonScripts(menu, menu.buttontable, 1, 4)
		SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(ReadText(1001, 3408), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, not menu.mode, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_BACK", true)), 1, 4)
		Helper.setButtonScript(menu, nil, menu.buttontable, 1, 4, menu.buttonShowMap)
		--- COMM
		Helper.removeButtonScripts(menu, menu.buttontable, 1, 6)
		if IsSameComponent(rowdata, menu.playership) then
			SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(ReadText(1001, 1002), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, not menu.mode, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_Y", true)), 1, 6)
			Helper.setButtonScript(menu, nil, menu.buttontable, 1, 6, menu.buttonBroadcast)
		else
			SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(ReadText(1001, 3216), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, not menu.mode, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_Y", true)), 1, 6)
			Helper.setButtonScript(menu, nil, menu.buttontable, 1, 6, menu.buttonComm)
		end
		--- DETAILS
		Helper.removeButtonScripts(menu, menu.buttontable, 1, 8)
		local active = false
		local recycle = false
		if not menu.mode then
			active = true
		elseif menu.mode == "selectobject" then
			if Helper.checkObjectSelectConditions(rowdata, menu.modeparam) then
				active = true
			end
		elseif menu.mode == "sellship" then			
			if not IsSameComponent(rowdata, menu.playership) and (not GetBuildAnchor(rowdata)) then
				local pilot = GetComponentData(rowdata, "pilot")
				if (not pilot) or (not GetNPCBlackboard(pilot, "$shiptrader_docking")) then
					if GetTotalValue(rowdata, true, GetContextByClass(menu.modeparam[2], "container")) then
						active = true
						if fitsindock then
							recycle = true
						end
					end
				end
			end
		end
		if menu.realmode == "recycleship" then -- adjust the buttons
			Helper.removeButtonScripts(menu, menu.buttontable, 1, 6)
			SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(ReadText(360001, 5), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, recycle, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_Y", true)), 1, 6)
			Helper.setButtonScript(menu, nil, menu.buttontable, 1, 6, menu.buttonRecycle)
			SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(menu.mode and ReadText(1001, 2917) or ReadText(1001, 2961), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, active, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_X", true)), 1, 8)
		else
			SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(menu.mode and ReadText(1001, 3102) or ReadText(1001, 2961), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, active, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_X", true)), 1, 8)
		end		
		Helper.setButtonScript(menu, nil, menu.buttontable, 1, 8, menu.buttonDetails)
	else
		Helper.updateCellText(menu.infotable, 2, 1, "")
		--- SHOW ON MAP
		Helper.removeButtonScripts(menu, menu.buttontable, 1, 4)
		SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(ReadText(1001, 3408), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, false, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_BACK", true)), 1, 4)
		--- COMM
		Helper.removeButtonScripts(menu, menu.buttontable, 1, 6)
		SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(ReadText(1001, 3216), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, false, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_Y", true)), 1, 6)
		--- DETAILS
		Helper.removeButtonScripts(menu, menu.buttontable, 1, 8)
		SetCellContent(menu.buttontable, Helper.createButton(Helper.createButtonText(menu.mode and ReadText(1001, 3102) or ReadText(1001, 2961), "center", Helper.standardFont, 11, 255, 255, 255, 100), nil, false, false, 0, 0, 150, 25, nil, Helper.createButtonHotkey("INPUT_STATE_DETAILMONITOR_X", true)), 1, 8)
	end
end

function menu.onSelectElement()
end

function menu.onCloseElement(dueToClose)
	if dueToClose == "close" then
		Helper.closeMenuAndCancel(menu)
		menu.cleanup()
	else
		Helper.closeMenuAndReturn(menu)
		menu.cleanup()
	end
end

function menu.addContainerRow(setup, component, iteration)
	local subordinates = GetSubordinates(component)
	for i = #subordinates, 1, -1 do
		if IsComponentClass(subordinates[i], "ship_xs") then
			table.remove(subordinates, i)
		elseif menu.mode == "sellship" and (not GetComponentData(subordinates[i], "issellable")) then
			table.remove(subordinates, i)
		end
	end
	menu.subordinates[tostring(component)] = subordinates or {}

	local name, numtrips = GetComponentData(component, "name", "numtrips")
	if menu.mode ~= "sellship" and IsSameComponent(menu.autopilottarget, component) then
		name = ">> " .. name
	end
	for i = 1, iteration do
		name = "   " .. name
	end

	if numtrips > 0 then
		menu.tripheader = true
		name = name .. " (" .. numtrips .. "/" .. menu.maxtrips .. ")"
	end
		
	local storage = GetStorageData(component)
	local fuelamount = GetComponentData(component, "cargo")["fuelcells"] or 0
	local fuelcapacity = GetWareCapacity(component, "fuelcells")
	if menu.mode == "sellship" then
		local totalprice = GetTotalValue(component, true, GetContextByClass(menu.modeparam[2], "container"))

		if next(storage) and storage.capacity > 0 then
			if IsComponentClass(component, "station") or fuelcapacity == 0 then
				setup:addSimpleRow({ 
					#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
					name,
					Helper.createFontString((totalprice > 0 and ConvertMoneyString(totalprice, false, 0, false, true) or "-") .. " " .. ReadText(1001, 101), false, "right")
				}, component, {1, 2, 2})
			else
				setup:addSimpleRow({ 
					#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
					name,
					Helper.createFontString(ConvertIntegerString(fuelamount, true, 4, true) .. " / " .. ConvertIntegerString(fuelcapacity, true, 4, true), false, "right"),
					Helper.createFontString((totalprice > 0 and ConvertMoneyString(totalprice, false, 0, false, true) or "-") .. " " .. ReadText(1001, 101), false, "right")
				}, component, {1, 1, 1, 2})
			end
		else
			setup:addSimpleRow({ 
				#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
				name,
				Helper.createFontString((totalprice > 0 and ConvertMoneyString(totalprice, false, 0, false, true) or "-") .. " " .. ReadText(1001, 101), false, "right")
			}, component, {1, 2, 2})
		end
	else
		local warning = Helper.hasObjectWarning(component)
		if warning > 0 then
			if next(storage) and storage.capacity > 0 then
				if IsComponentClass(component, "station") or fuelcapacity == 0 then
					setup:addSimpleRow({ 
						#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
						name,
						Helper.createFontString(ConvertIntegerString(storage.stored, true, 4, true) .. " / " .. ConvertIntegerString(storage.capacity, true, 4, true) .. " " .. ReadText(1001, 110), false, "right"),
						Helper.createIcon("workshop_error", false, warning == 2 and 255 or 192, warning == 2 and 0 or 192, 0, 100, 0, 0, Helper.standardTextHeight, Helper.standardTextHeight)
					}, component, {1, 2, 1, 1})
				else
					setup:addSimpleRow({ 
						#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
						name,
						Helper.createFontString(ConvertIntegerString(fuelamount, true, 4, true) .. " / " .. ConvertIntegerString(fuelcapacity, true, 4, true), false, "right"),
						Helper.createFontString(ConvertIntegerString(storage.stored, true, 4, true) .. " / " .. ConvertIntegerString(storage.capacity, true, 4, true) .. " " .. ReadText(1001, 110), false, "right"),
						Helper.createIcon("workshop_error", false, warning == 2 and 255 or 192, warning == 2 and 0 or 192, 0, 100, 0, 0, Helper.standardTextHeight, Helper.standardTextHeight)
					}, component, {1, 1, 1, 1, 1})
				end
			else
				setup:addSimpleRow({ 
					#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
					name,
					Helper.createIcon("workshop_error", false, warning == 2 and 255 or 192, warning == 2 and 0 or 192, 0, 100, 0, 0, Helper.standardTextHeight, Helper.standardTextHeight)
				}, component, {1, 3, 1})
			end
		else
			if next(storage) and storage.capacity > 0 then
				if IsComponentClass(component, "station") or fuelcapacity == 0 then
					setup:addSimpleRow({ 
						#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
						name,
						Helper.createFontString(ConvertIntegerString(storage.stored, true, 4, true) .. " / " .. ConvertIntegerString(storage.capacity, true, 4, true) .. " " .. ReadText(1001, 110), false, "right")
					}, component, {1, 2, 2})
				else
					setup:addSimpleRow({ 
						#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
						name,
						Helper.createFontString(ConvertIntegerString(fuelamount, true, 4, true) .. " / " .. ConvertIntegerString(fuelcapacity, true, 4, true), false, "right"),
						Helper.createFontString(ConvertIntegerString(storage.stored, true, 4, true) .. " / " .. ConvertIntegerString(storage.capacity, true, 4, true) .. " " .. ReadText(1001, 110), false, "right")
					}, component, {1, 1, 1, 2})
				end
			else
				setup:addSimpleRow({ 
					#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(component)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
					name
				}, component, {1, 4})
			end
		end
	end
	if IsComponentClass(component, "station") then
		AddKnownItem("stationtypes", GetComponentData(component, "macro"))
	elseif IsComponentClass(component, "ship_xl") then
		AddKnownItem("shiptypes_xl", GetComponentData(component, "macro"))
	elseif IsComponentClass(component, "ship_l") then
		AddKnownItem("shiptypes_l", GetComponentData(component, "macro"))
	elseif IsComponentClass(component, "ship_m") then
		AddKnownItem("shiptypes_m", GetComponentData(component, "macro"))
	elseif IsComponentClass(component, "ship_s") then
		AddKnownItem("shiptypes_s", GetComponentData(component, "macro"))
	elseif IsComponentClass(component, "ship_xs") then
		AddKnownItem("shiptypes_xs", GetComponentData(component, "macro"))
	end
		
	if menu.extendedcategories[tostring(component)] then
		for _, subordinate in ipairs(subordinates) do
			menu.addContainerRow(setup, subordinate, iteration + 1)
		end
	end
end

function menu.createSection(setup, name, header, array, nonetext, addheader)
	if addheader then
		if name == "ships" then
			setup:addSimpleRow({ 
				#array > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[name] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
				header,
				ReadText(20205, 800),
				(menu.mode == "sellship") and ReadText(1001, 2808) or ReadText(1001, 2958)
			}, nil, {1, 1, 1, 2}, false, Helper.defaultHeaderBackgroundColor)
		else
			setup:addSimpleRow({ 
				#array > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[name] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
				header,
				(menu.mode == "sellship") and ReadText(1001, 2808) or ReadText(1001, 2958)
			}, nil, {1, 2, 2}, false, Helper.defaultHeaderBackgroundColor)
		end
	else
		setup:addSimpleRow({ 
			#array > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[name] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
			header
		}, nil, {1, 4}, false, Helper.defaultHeaderBackgroundColor)
	end
	if menu.extendedcategories[name] then
		if name == "ships" and menu.faction == "player" then
			local subordinates = GetSubordinates(menu.playership)
			for i = #subordinates, 1, -1 do
				if IsComponentClass(subordinates[i], "ship_xs") then
					table.remove(subordinates, i)
				elseif menu.mode == "sellship" and (not GetComponentData(subordinates[i], "issellable")) then
					table.remove(subordinates, i)
				end
			end
			menu.subordinates[tostring(menu.playership)] = subordinates

			setup:addSimpleRow({ 
				#subordinates > 0 and Helper.createButton(Helper.createButtonText(menu.extendedcategories[tostring(menu.playership)] and "-" or "+", "center", Helper.standardFont, Helper.standardFontSize, 255, 255, 255, 100), nil, false, true, 0, 0, 0, Helper.standardTextHeight) or "", 
				GetComponentData(menu.playership, "name")
			}, menu.playership, {1, 4})
			AddKnownItem("shiptypes_s", GetComponentData(menu.playership, "macro"))

			if menu.extendedcategories[tostring(menu.playership)] then
				for _, subordinate in ipairs(subordinates) do
					menu.addContainerRow(setup, subordinate, 1)
				end
			end
		end
		if #array == 0 and not (name == "ships" and menu.faction == "player") then
			setup:addSimpleRow({ 
				Helper.getEmptyCellDescriptor(), nonetext 
			}, nil, {1, 4})
		elseif #array ~= 0 then
			for i, component in ipairs(array) do
				menu.addContainerRow(setup, component, 0)
			end
		end
	end
end

-- set button scripts
function menu.addContainerButtonScript(component, counter)
	if #menu.subordinates[tostring(component)] > 0 then
		local row = counter
		Helper.setButtonScript(menu, nil, menu.selecttable, row, 1, function () return menu.buttonExtend(component, row) end)
	end
	counter = counter + 1
	if menu.extendedcategories[tostring(component)] then
		for _, subordinate in ipairs(menu.subordinates[tostring(component)]) do
			counter = menu.addContainerButtonScript(subordinate, counter)
		end
	end
	return counter
end

function menu.setButtonsForSection(name, array, offsetrow)
	if #array > 0 then
		local row = offsetrow
		Helper.setButtonScript(menu, nil, menu.selecttable, row, 1, function () return menu.buttonExtend(name, row) end)
	end
	local nooflines = offsetrow + 1
	if menu.extendedcategories[name] then
		if name == "ships" and menu.faction == "player" then
			nooflines = menu.addContainerButtonScript(menu.playership, nooflines)
		end
		if #array == 0 and not (name == "ships" and menu.faction == "player") then
			nooflines = nooflines + 1
		elseif #array ~= 0 then
			for i, component in ipairs(array) do
				nooflines = menu.addContainerButtonScript(component, nooflines)
			end
		end
	end
	return nooflines
end

init()
Author: jth 
X Rebirth version: 4.00
StationRecycle v0.07 apr 6 2017
================================
Adds the ability to recycle or destroy ships at Player Shipyards or NPC Shipyards

Please be aware that this is a beta release and that you should back up your save games before using it. Save games zip up very efficiently to about 7% of the original size.

Installation and Compatibility with other mods
==============================================
To install it extract and copy the "shiprecycle" folder to the "Steam\steamapps\common\X Rebirth\extensions" folder (create the extensions folder if you don't have it already) or subscribe to it from Steam and restart the game.

This mod interacts with the player via the ShipTrader menu and replaces The "Sell a ship" option with "Sell or Reycle a ship". 

This mod patches Egosoft's ShipTrader.xml file and adds customised versions of menu_property.lua and menu_buildcost.lua
 
X Rebirth will save some of the variables and the state of the Ship Recycle cues as part of a normal save game. Do not remove this mod part way through recycling a ship. If you decide not to use this mod any more just remove the "ShipRecycle" folder or unsubscribe it from Steam and restart the game.

=== How to Use ===
Fly to the zone that contains the shipyard that you want to use to recycle your ship
Open communications with the right Ship Trader for the size of vessel that you are recycling
Pick the "Sell or Recycle a ship" menu option
Select the ship and then click on either the Recycle or Sell button.
	The Sell button sells the ship in the normal way using standard Egosoft code at the standard price
	The Recycle button opens up the Recycle Cost menu for the selected ship where you can see the recycling information
	Then pick "Yes, recycle this ship"
Sit back and watch the ship move into the docking cradle and then observe the hull, weapons, drones, ammunition, cargo and crew getting recycled

=== Upgrading from version 1 ===
After a clean start of X Rebirth with version 2 or later of this script the next ship that is recycled with a specific ship trader will convert all the NPC's that were created with version 1 by that shiptrader from player owned to hireable and pay the player for them. 

The old player owned NPC's will be destroyed. The re-created NPC's will have the same name, type, race, macro and skill levels. 

The conversion will skip any NPC's created by version 1 of this script that are not on the Shipyard and put an entry in the logbook for each skipped NPC so that you can identify them. There is a potential issue where these version 1 NPC may disappear over time leaving your ship without certain crew.

You need to recycle a ship at all the shiptraders that you used for recycling in version 1 to get all NPC's converted to hireable NPC's.

Some of the NPC's (the first Defense Officer and the first Engineer) that were recycled with version 1 were probably assigned to the shipyard if you did not already have a Defense Officer and Engineer. The upgrade will remove them from their posts and re-create them as hireable again.

The Recycle Ship mod :-
-----------------------------------
Allows recycling of L and XL ships in Player Shipyards and NPC Shipyards
Uses a customised version of Egosoft's PropertyMenu and BuildCostMenu GUI menus to select the ship to be recycled and show you what wares will be recovered
Checks a number of pre-requisites to make sure that recycling can proceed and notifies player if there are any problems before allowing the player to continue. 
PropertyMenu checks that the recycling ship will fit into the individual ShipTrader's ship cradle. 
BuildCostMenu checks that the shipyard has enough food, energy and construction drones present and shows you what will be recycled.

Recycles hull wares taking into account the state of the hull at the time
Recycles operational Weapons and Shields plus installed drones, ammunition and cargo
When recycling cargo it pays the full price for any wares that will fit in station storage and 50% if they do not fit or are not standard wares for a shipyard
If the Shipyard is NPC owned then the player is paid for the ship in the same way as the current Sell a ship
Consumes energy and food rations to carry out recycling
Moves ship into appropriate ship cradle and chops the hull up piece by piece
Pays player for crew (captain, defense officer, engineer and architect) and recreates NPC's with same skills as ship crew on shipyard where they can be hired by player. This means that if you spend time training crew then their replacement will also have the benefit of the training.
Will try to put recreated crew in the bar if it can find space there otherwise picks any personnel docking bay that has space.
Maintains individual ShipTrader locking so that an individual ship trader can only do one thing at a time
Aborts recycle if ship is destroyed before it gets into dock.
Logs ship recycling in player log book and to debug.log so that the recycling process can be checked and diagnosed 
Checks selling price of NPC's and if greater than max allowed then compensates by dividing by 100

=== Known issues ===
If there is no space on the shipyard for recreating the crew then they will not be recreated but you will still be paid for the old crew.
The amount that is paid for a crew contract is calculated by calling the Egosoft FeeCalculation cue from NPC_Staff without applying any recycling factors as its going to be pretty random anyway. To quote from the code <!-- 1/4 = skill based, 3/4 = random -->. It will almost definitely be different to what you paid for that crew member in the first place.
If you leave recycled crew on the shipyard for too long then they will eventually get cleaned up by the Egosoft station crew script and replaced by someone else with different skills.
Using multiple ShipTraders from the same shipyard at the same time may have unfortunate consequences, do not attempt to recycle two ships at the same time.
When recycling there is no check that recycled wares can fit in station storage for anything except ship cargo. There were no checks at all before v0.04

=== Recommendations for using the mod ===
Although the restriction on the recycled ship having to be in the same zone as the player is gone I would strongly recommend that you get the recycled ship into the same zone as the shipyard before starting to recycle it as a lot can happen in the time that the recycled ship flies to the shipyard

=== ToDo ===
Small ShipTraders if suitable case made by players and enough demand, ware amounts are rather small for m ships.
Fly some construction drones around during chop up phase
The two customised versions of menu_property.lua and menu_buildcost.lua are based on the ones from 3.6x so don't have the extra bells and whistles from 4.x might be worth porting the changes to the 4.x versions at some time if there is enough demand

=== Diagnosing issues ===

These instructions are for Windows 7 64 bit, please adjust for other versions

Start X Rebirth in debug logging mode by adding  "-debug all -logfile debug.log" to the end of the command line

In my case this would look like

"C:\Program Files (x86)\Steam\steamapps\common\X Rebirth\XRebirth.exe" -debug all -logfile debug.log

That will create a debug.log file at the same level as your save game folder

Recycle a ship, then get a command prompt in the same folder as debug.log by shift right clicking and selecting "open command window here"

Then search for all NPC_Shiptrader lines with

find "NPC_Shiptrader" debug.log > results.txt

Open results.txt

This is a successful recycle of a Rahanas

[Scripts] *** Context:md.NPC_Shiptrader.DefaultComm<inst:6f029>: Architect conversation started: default, actor=0x5930c, Kareen Claassen
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f072>: <event_conversation_next_section> section: 'cArch_sellship'
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f11a>: <event_conversation_next_section> section: 'cArch_recycleship'
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f11a>: Missile Warelist entries 0 []
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f11a>: Ammoplan is []
[=ERROR=] shiprecycle_menu_cost Recycling - Rahanas QTubes
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f313>: <event_conversation_next_section> section: 'cArch_recycleshipselected'
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f371>: <event_conversation_next_section> section: 'cArch_recycleshipconfirmed'
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f371>: Rahanas QTubes selected for Recycling
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f371>: Rahanas QTubes is of size dock_l
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f371>: Kareen Claassen has an LV Shipyard
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f371>: LV Shipyard is capable of docking [tag.dock_l] ships
[Scripts] *** Context:md.NPC_Shiptrader.LogWriter<inst:6f372>: Initial Station Cargo, foodrations 7926, scanningarray 117, reinforcedmetalplating 129, plasmaflowregulator 42, microchips 231, holtzmanfieldgenerator 58, fusionreactor 48, bioopticwiring 264, machinegunturret 16, shieldgenerator 6, energycells 14878, 
[Scripts] *** Context:md.NPC_Shiptrader.LogWriter<inst:6f373>: Build wares for Rahanas QTubes - 9 Wares, units_size_l_kit_container_02_macro, bioopticwiring - 98, microchips - 86, reinforcedmetalplating - 48, scanningarray - 44, holtzmanfieldgenerator - 22, fusionreactor - 18, plasmaflowregulator - 16, machinegunturret - 8, shieldgenerator - 3, 
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f371>: Shiptrader_docking <componentslot:0x5931d,connection01>
[Scripts] *** Context:md.NPC_Shiptrader.SectionHandler<inst:6f371>: Rahanas QTubes 0x59025 told to move into dock

[Scripts] *** Context:md.NPC_Shiptrader.UpgradesFinished<inst:726d0>: Rahanas QTubes now being recycled
[Scripts] *** Context:md.NPC_Shiptrader.RecycleCrew<inst:72712>: 1/2 commander Kaylen Cheram 0x5902a now being recycled
[Scripts] *** Context:md.NPC_Shiptrader.RecycleCrew<inst:72712>: Received 67 730 Credits from Capital Ship Dealer Kareen Claassen for Captain Kaylen Cheram's contract
[Scripts] *** Context:md.NPC_Shiptrader.RecycleCrew<inst:72712>: Assigned commander Kaylen Cheram 0x72713 to Station Administration
[Scripts] *** Context:md.NPC_Shiptrader.RecycleCrew<inst:72712>: 2/2 engineer Cerise Gisler 0x59029 now being recycled
[Scripts] *** Context:md.NPC_Shiptrader.RecycleCrew<inst:72712>: Received 36 101 Credits from Capital Ship Dealer Kareen Claassen for Engineer Cerise Gisler's contract
[Scripts] *** Context:md.NPC_Shiptrader.RecycleCrew<inst:72712>: Assigned engineer Cerise Gisler 0x72722 to Station Administration
[Scripts] *** Context:md.NPC_Shiptrader.LogWriter<inst:72730>: Hull Wares added to Capital Shipyard I, bioopticwiring - 98, microchips - 86, reinforcedmetalplating - 48, scanningarray - 44, holtzmanfieldgenerator - 22, fusionreactor - 18, plasmaflowregulator - 16, machinegunturret - 8, shieldgenerator - 3, 
[Scripts] *** Context:md.NPC_Shiptrader.LogWriter<inst:72731>: Extra Wares added to Capital Shipyard I, drp_cargolifter - 10, microchips - 5000, 
[Scripts] *** Context:md.NPC_Shiptrader.RecycleFinished<inst:7438c>: Recycling of Rahanas QTubes in zone Gushing Spring - done
[Scripts] *** Context:md.NPC_Shiptrader.LogWriter<inst:7438d>: Final Station Cargo, drp_cargolifter 10, foodrations 7686, scanningarray 161, reinforcedmetalplating 177, plasmaflowregulator 58, microchips 5317, holtzmanfieldgenerator 80, fusionreactor 66, bioopticwiring 362, machinegunturret 24, shieldgenerator 9, energycells 14438, 
[Scripts] *** Context:md.NPC_Shiptrader.DelayedDestroyShip<inst:7438e>: Rahanas QTubes destroyed
[Scripts] *** Context:md.NPC_Engineer.NPC_Destroyed<inst:66271>: NPC_Destroyed
[Scripts] *** Context:md.NPC_Staff.NPC_Destroyed<inst:67de7>: NPC_Destroyed


=== Release history ===

 - [6.4.2017 - V0.07 Public Beta] 
	shiprecycle_menu_cost gui - Compensate for format of version string changing in 4.10 RC3 and add extra paranoia when checking version to prevent crashing the GUI

 - [24.2.2016 - V0.06 Public Beta] 
	shiprecycle_menu_cost gui - Add remote logging via md script to remove false positive Error messages, caused by DebugError logging commands, in debug.log that were actually informational
	shiprecycle_menu_cost gui - Compensate for parameter changes to Encyclopaedia API in 4.00 RC2 to prevent Encyclopaedia buttons crashing the GUI
	shiprecycle_menu_cost gui - Apply a 90% recycling factor to ship hull wares	
	shiprecycle_menu_cost gui - Rebalance prices to track what shipbuilders pay to buy back ships (80%), drones (85%) and ammunition (90%)	
	shiprecycle_menu_cost gui - Add an extra 10% handling charge to wares that could be sold to the station by the player before the ship is recycled. As the Teladi say "time is money".
	shiprecycle_menu_cost gui - Changed API call used for calculating free space to take into account the available space for the ware instead of total available space
	shiprecycle_menu_cost gui - Fix issue with calculating refund when recycling where there is no storage space for a specific ware. Now correctly refunds 50%
	shiprecycle_menu_cost gui - Adjusted on screen messages a litle for when ware doesn't all fit into shipyard storage
	shiprecycle_menu_cost gui - Suppress Drone section when there are no drones
	
 - [11.1.2016 - V0.05 Public Beta] 
	shiprecycle_menu_cost gui - Fixed failure to recycle any ships when there was zero energycells or foodrations on the shipyard which will happen with a brand new player shipyard
 - [10.12.2015 - V0.04 Public Beta] 
	Completely rewrote the ship selection user interface using customised versions of menu_property.lua and menu_buildcost.lua
	Moved ship selection logic out of md script and into the GUI
	This means that you cannot select a ship for recycling that does not fit in the ShipTraders cradle unlike previous versions where this was allowed initially but detected later and the process aborted
	RecycleCostMenu checks the shipyard prerequisites before allowing you to OK which again avoids a later abort for lack of ShipTrader resources
	The GUI API calls can get the shields and turrets from a ship that is Out Of Zone (OOZ) so the restriction on the recycled ship being in the same zone as the player has gone
	No longer shares the sellship confirm menu so it makes one less change to ShipTrader.xml
	Now recycles installed drones, ammunition and cargo
	When recycling cargo it pays the full price for any wares that will fit in station storage and 50% if they do not fit or are not standard wares for a shipyard
	When cloning the crew to the shipyard bar it now keeps their original names
	Now multi lingualwhich means that a lot of the messages will have changed subtly to fit existing translated words
	Now makes a single fund transfer for all crew contracts to cut down on event monitor messages
	Now uses the FormatThousands library to format the money amounts with a separator between thousands
	Removed ship selection logic and its event monitor messages from md script  
	Removed ship building ware estimate code from md script as this is now done in the RecycleCostMenu lua script which means that it no longer builds a dummy ship to find the necessary wares	
	Removed ship turret and shields finding code from md script as this is now done in the RecycleCostMenu lua script	
	Modified the station stocking code to use the less complicated array that RecycleCostMenu creates
	Replaced the turret and shields stocking code with a simple loop that adds the drones, ammunition and cargo to the station from another array that RecycleCostMenu creates
 - [27.3.2015 - V0.03 Public Beta] 
	Interoperability - added support for Combined Docks example code by UniTrader even though its not on Steam or Nexus
 - [13.3.2015 - V0.02 Public Beta] 
	Major change - Removed use of boarding pods to transport crew onto shipyard, crew contracts now sold to the shipdealer and they stay on board ship
	Pays player for crew and recreates NPC's with same skills as ship crew on shipyard where they can be hired by player.
	Tries to put recreated crew in the bar if there is room otherwise picks any docking bay that has space.
	Converts the player owned NPC's that were transported to the shipyard via boarding pod while running version 1 of this script into hireable NPC's and pays player for them
	Fixes an issue where recycling was refused due to insufficient shipyard resources caused the commander of the ship that was being recycled to get a blackboard entry of $shiptrader_docking added which prevented that ship from ever being recycled or sold. 
 - [14.12.2014 - V0.01 Public Beta] 
	Initial Release 
	<?xml version="1.0" encoding="utf-8"?>
<content id="" name="" description="" author="jth" version="7" date="2017-04-06" save="0" lastupdate="">
  <dependency version="361"/>
  <text language="7" name="Ship Recycle" description="A ship recycle script" author="jth"/>
  <text language="33" name="Ship Recycle" description="Un script navire de recyclage" author="jth"/>
  <text language="34" name="Ship Recycle" description="Una secuencia de comandos de reciclaje nave" author="jth"/>
  <text language="39" name="Ship Recycle" description="Uno script nave riciclo" author="jth"/>
  <text language="44" name="Ship Recycle" description="A ship recycle script" author="jth"/>
  <text language="49" name="Ship Recycle" description="Ein Schiff recycle Skript" author="jth"/>
</content>
