//FTTList - [2020-04-13 11:57:47]
#ifndef _TTLIST_H_
#define _TTLIST_H_

#include "common.h"

/*
00168F2E TTList<TTDListNode<TTSPtr<TNMVert>> *>::~TTList()
00168CD4 TTList<TTDListNode<TTSPtr<TNMVert>> *>::Insert(TTDListNode<TTSPtr<TNMVert>> *)
00168E60 TTList<TTDListNode<TTSPtr<TNMVert>> *>::Remove(TTDListNode<TTSPtr<TNMVert>> *)

00169A68 TTList<fpoint2<14u>>::~TTList()
00169694 TTList<fpoint2<14u>>::Insert(fpoint2<14u>)

00168B5E TTList<TTDList<TTSPtr<TNMVert>> *>::Remove(TTDList<TTSPtr<TNMVert>> *)
00168BA6 TTList<TTDList<TTSPtr<TNMVert>> *>::Insert(TTDList<TTSPtr<TNMVert>> *)
00168F46 TTList<TTDList<TTSPtr<TNMVert>> *>::~TTList()

00169824 TTList<TNMAStar *>::~TTList()
00169604 TTList<TNMAStar *>::InsertSorted(TNMAStar *)
00169670 TTList<TNMAStar *>::Pop()

TTList_point
*/

typedef int (*pfun_TTList_unk1)(int*, int*);

template <typename T>
class TTList {
public:
  struct TTListNode {
    T m;
    TTListNode* next;
  };

  TTList() {
    pBegin_0 = nullptr;
    pEnd_4 = 0;
    dCount_8 = false;
    pFun_C = nullptr;
  };

  //00169824  TTList_point
  ~TTList() {
    for (TTListNode* p = pBegin_0; p != nullptr;) {
      TTListNode* n = p->next;
      delete p;
      p = n;
    }
  };

  //00168BA6
  void Insert(T t) {
    TTListNode* p = new TTListNode();
    p->m = t;
    p->next = nullptr;  //.text:00168BB8   STRD.W R5, R6, [R0]
    if (pBegin_0 == nullptr) {
      pBegin_0->next = p;
    }
    //loc_168BC2
    if (pEnd_4) {
      pEnd_4->next = p;
    }
    //loc_168BC8
    pEnd_4 = p;
    dCount_8++;
  };

  //00169604
  void InsertSorted(T t) {
    TTListNode* pnode = new TTListNode;
    pnode->m = t;
    pnode->next = nullptr;  //0016961C
    int var_20;
    T var_24;
    TTListNode* dr6 = nullptr;
    for (TTListNode* pr5 = &pBegin_0[0]; pr5 != nullptr; pr5 = pr5->next) {
      //loc_16962A
      var_24 = pr5->m;
      if (pFun_C(&var_20, &var_24)) {  //??? pFun_C不知道在何时赋值的
        //loc_169656
        TTListNode* pr0 = pBegin_0;
        if (dr6) {
          //0016965A
          pr0 = ++dr6;
        }
        pr0 = pnode;
        pnode->next = pr5;
        break;
      }
      //00169638
      dr6 = pr5;
    }

    //00169642
    if (dr6 == nullptr) {
      pBegin_0 = pnode;
    }
    //loc_169648
    if (pEnd_4 != nullptr) {
      pEnd_4->next = pnode;
      pEnd_4 = pnode;
    }

    //loc_169666
    dCount_8++;
  };

  //00168B5E
  void Remove(T t) {
    if (pBegin_0 == nullptr)
      return;  //locret_168B84
    //00168B66
    TTListNode** pr4 = &pBegin_0;
    TTListNode* pPri_r3 = nullptr;
    while (*pr4 != nullptr) {  //loc_168B7E
      //loc_168B74
      if ((*pr4)->m == t) {
        //loc_168B86
        if (pPri_r3) {
          pPri_r3->next = (*pr4)->next;
        }
        //loc_168B8C
        if (pBegin_0->m == t) {
          pBegin_0 = (*pr4)->next;
        }

        if (pEnd_4->m == t) {
          pEnd_4 = pPri_r3;
        }

        delete (*pr4);
        dCount_8--;
        return;
      } else {
        pPri_r3 = *pr4;
      }
    }
  };

  //00169670
  T Pop() {
    /*
    .text:00169670   PUSH            {R4,R5,R7,LR}
    .text:00169672   MOV             R4, R0              R4 = R0 = this
    .text:00169674   LDR             R0, [R0]            R0 = pBegin_0
    .text:00169676   LDRD.W          R5, R1, [R0]        R5 = pBegin_0->m R1 = pBegin_0->next
    .text:0016967A   CBNZ            R1, loc_169680
    .text:0016967C   MOVS            R1, #0
    .text:0016967E   STR             R1, [R4,#4]
    .text:00169680
    .text:00169680 loc_169680:                   @ CODE XREF: TTList<TNMAStar *>::Pop()+A↑j
    .text:00169680   CMP             R0, #0
    .text:00169682   STR             R1, [R4]
    .text:00169684   Beq             loc_16968A
    .text:00169686   BLX             j__ZdlPv    @ operator delete(void *)
    .text:0016968A
    .text:0016968A loc_16968A:                   @ CODE XREF: TTList<TNMAStar *>::Pop()+14↑j
    .text:0016968A   LDRB            R0, [R4,#8]
    .text:0016968C   SUBS            R0, #1
    .text:0016968E   STRB            R0, [R4,#8]
    .text:00169690   MOV             R0, R5
    .text:00169692   POP             {R4,R5,R7,PC}
    */
    //这个函数的作用是弹出 pBegin_0 当中的第一个结点

    T r = pBegin_0->m;  //原始的代码的当中没有考虑到pBegin_0是否为nullptr
    TTListNode* pn = pBegin_0->next;
    if (pBegin_0->next == nullptr) {  //0016967A
      pEnd_4 = nullptr;
      pn = nullptr;
    }
    //loc_169680
    pBegin_0 = pn;
    if (pBegin_0) {
      delete pBegin_0;
    }
    //loc_16968A
    dCount_8--;
    return r;
  };

  TTListNode* pBegin_0;
  TTListNode* pEnd_4;
  int8_t dCount_8;          //只用了一个字节表示结点长度，List最大长度只能是255
  pfun_TTList_unk1 pFun_C;  //??? 不知道，是在哪儿赋值的
};

#endif  //_FTTLIST_H_