/**************************************************************************
  Network Satellite Editor Program

                                                           2001. 08. 01
                                                                   이니

  Unit_Network

  - Network 처리 부분
***************************************************************************/


/**************************************************************************
  Include 및 시스템 설정
***************************************************************************/
#include <vcl.h>
#pragma hdrstop

#include "Unit_Main.h"
#include "Unit_File.h"
#include "Unit_Network.h"
#include "Unit_NetworkEditor.h"
#include "Unit_Transponder.h"
#include "Unit_TransponderEditor.h"
#include "Unit_Program.h"
#include "Unit_Miscellany.h"
#include "Unit_Import.h"


/**************************************************************************
  PrintNetwork
  - Network 리스트를 출력한다
***************************************************************************/
void __fastcall PrintNetwork()
{

 int          itNetworkIndex, itNetworkOrder, itNetworkLastOrder = LastNetworkOrder(),
              itPreviousStartIndex = Main->LbNetworkList->TopIndex,
              itPreviousIndex = Main->LbNetworkList->ItemIndex;
 String       stTemp;



 // 리스트를 Clear 한다
 Main->LbNetworkList->Items->Clear();
 Main->Repaint();


 FillMemory(&Main->PrintingNetwork, sizeof(Main->PrintingNetwork), 0xFF);


 for(itNetworkOrder = 1; itNetworkOrder <= itNetworkLastOrder; itNetworkOrder ++) {
   itNetworkIndex = NetworkOrderToNetworkIndex(itNetworkOrder);

   if(itNetworkIndex >= 0 && Main->Network_VList[itNetworkIndex].Status == DATA_OCCUPY) {
     stTemp = Format("%-12s    ", ARRAYOFCONST(((String)Main->Network_List[itNetworkIndex].Name)));

     switch(Main->Network_List[itNetworkIndex].Config_2 & 0x0F) {
       case 0 :
       case 1 :
       case 2 :
       case 3 :
       case 4 :
       case 5 :
       case 6 :
         stTemp = stTemp + "Standard     ";
         break;

       case 7 :
       case 8 :
         stTemp = stTemp + "Universal    ";
         break;

       case USERFREQUENCY_IN_ITEMLIST :
         stTemp = stTemp + "User         ";
         break;

       default                        :
         stTemp = stTemp + "Unknown      ";
         break;
     }

     if(Main->Network_List[itNetworkIndex].Config_2 == USERFREQUENCY_IN_ITEMLIST) {
       stTemp = stTemp + Format("%5d MHz     ", ARRAYOFCONST(((int)Main->Network_List[itNetworkIndex].UserLowLocal)));
      } else {
       stTemp = stTemp + Format("%5d MHz     ", ARRAYOFCONST(((int)(NetworkEditor->CbMasterFrequency->Items->Strings[Main->Network_List[itNetworkIndex].Config_2].SubString(13, 6).Trim().ToInt()))));
     }

     stTemp = stTemp + Format("[%0.3d]", ARRAYOFCONST(((int)NetworkTransponderNum(itNetworkIndex))));
//     stTemp = stTemp + Format("[%0.3d]", ARRAYOFCONST(((int)Main->Network_List[itNetworkIndex].Order)));

     Main->PrintingNetwork[Main->LbNetworkList->Items->Count] = itNetworkIndex;
     Main->LbNetworkList->Items->Add(stTemp);
   }
 }


 Main->LbNetworkList->TopIndex  = itPreviousStartIndex;
 Main->LbNetworkList->ItemIndex = itPreviousIndex;


 WriteLastIndex();
 PrintTransponder();

}


/**************************************************************************
  NetworkSubstitutionStandByNetwork
  - NetworkEditor 폼의 값을 Network List 변수에 대입한다
***************************************************************************/
void __fastcall NetworkSubstitutionStandByNetwork(int itNetworkIndex)
{

 int     LNBType = NetworkEditor->RgLNB->ItemIndex;


 strcpy(Main->Network_List[itNetworkIndex].Name, NetworkEditor->EdName->Text.c_str());

 if(LNBType == 1) {
   Main->Network_List[itNetworkIndex].UserLowLocal = NetworkEditor->CbUserFrequency->Value;
   Main->Network_List[itNetworkIndex].Config_2     = USERFREQUENCY_IN_ITEMLIST;
  } else {
   Main->Network_List[itNetworkIndex].UserLowLocal = 5150;
   Main->Network_List[itNetworkIndex].Config_2     = NetworkEditor->CbMasterFrequency->ItemIndex;
 }


 // 변수들 초기화
 Main->Network_List[itNetworkIndex].UserHighLocal     = 5150;

 Main->Network_List[itNetworkIndex].Config            = 0;
 Main->Network_List[itNetworkIndex].Config_3          = 0;
// Main->Network_List[itNetworkIndex].Config_4          = 0; 그대로 놔둠
 Main->Network_List[itNetworkIndex].Real_Ch_SATNumber = 0xFE;


 // On 과 Off의 위치가 폼에서는 바뀌어 있다. Xor 시켜서 On 을 1, Off 를 0 으로
 // 만든다음, LNB에 Or 연산을 하고 왼쪽으로 쉬프트 시켜 자리를 잡는다.
 Main->Network_List[itNetworkIndex].Config |= NetworkEditor->RgDiSEqC->ItemIndex;

 Main->Network_List[itNetworkIndex].Config =  Main->Network_List[itNetworkIndex].Config << 1;
 Main->Network_List[itNetworkIndex].Config |= NetworkEditor->Rg12V->ItemIndex;

 Main->Network_List[itNetworkIndex].Config =  Main->Network_List[itNetworkIndex].Config << 2;
 Main->Network_List[itNetworkIndex].Config |= NetworkEditor->Rg22KHz->ItemIndex;

 Main->Network_List[itNetworkIndex].Config =  Main->Network_List[itNetworkIndex].Config << 1;
 Main->Network_List[itNetworkIndex].Config |= NetworkEditor->RgLNBPower->ItemIndex;

 Main->Network_List[itNetworkIndex].Config =  Main->Network_List[itNetworkIndex].Config << 1;
 Main->Network_List[itNetworkIndex].Config |= 0;       // FTAOnly

}


/**************************************************************************
  NetworkSubstitutionStandByForm
  - Network List 변수의 값을 NetworkEditor 폼에 대입한다
***************************************************************************/
void __fastcall NetworkSubstitutionStandByForm(int itNetworkIndex)
{

 int     itLNB = Main->Network_List[itNetworkIndex].Config,
         itTemp;


 NetworkEditor->EdName->Text = Main->Network_List[itNetworkIndex].Name;

 itLNB = itLNB >> 1;        // FTAOnly

 NetworkEditor->RgLNBPower->ItemIndex = (itLNB & 0x01);
 itLNB = itLNB >> 1;

 NetworkEditor->Rg22KHz->ItemIndex    = (itLNB & 0x03);
 itLNB = itLNB >> 2;

 NetworkEditor->Rg12V->ItemIndex      = (itLNB & 0x01);
 itLNB = itLNB >> 1;

 NetworkEditor->RgDiSEqC->ItemIndex   = (itLNB & 0x07);


 if(Main->Network_List[itNetworkIndex].Config_2 == USERFREQUENCY_IN_ITEMLIST) {
   NetworkEditor->CbMasterFrequency->ItemIndex = 0;
   NetworkEditor->CbUserFrequency->Value       = Main->Network_List[itNetworkIndex].UserLowLocal;
   NetworkEditor->RgLNB->ItemIndex             = 1;
  } else {
   NetworkEditor->CbMasterFrequency->ItemIndex = Main->Network_List[itNetworkIndex].Config_2;
   NetworkEditor->CbUserFrequency->Value       = Main->Network_List[itNetworkIndex].UserLowLocal;
   NetworkEditor->RgLNB->ItemIndex             = 0;
 }

 NetworkEditor->LNBCheck(NULL);

}


/**************************************************************************
  NetworkAddClick
  - Network를 한 개 추가한다
***************************************************************************/
void __fastcall NetworkAddClick(TObject *Sender)
{

 int     itNetworkIndex = FirstEmptyNetworkList();


 NetworkEditor->FormInitialize();
 NetworkEditor->Tag = 0;

 NetworkEditor->ShowModal();

 // Tag 프로퍼티가 1 이면 OK 버튼을 누른 상태이다
 if(NetworkEditor->Tag) {
   Main->BackupData();
   Main->Modified = True;

   FillMemory(&Main->Network_List[itNetworkIndex], sizeof(Main->Network_List[itNetworkIndex]), 0);
   Main->Network_VList[itNetworkIndex].Status = DATA_OCCUPY;
   Main->Network_VList[itNetworkIndex].Order  = LastNetworkOrder() + 1;

   NetworkSubstitutionStandByNetwork(itNetworkIndex);

   // 갱신한 정보를 출력한다
   PrintNetwork();

   Main->LbNetworkList->ItemIndex = Main->LbNetworkList->Items->Count - 1;
   Main->LbTransponderList->TopIndex  = 0;
   Main->LbTransponderList->ItemIndex = -1;

   TransponderAddClick(NULL);
 }

}


/**************************************************************************
  NetworkModifyClick
  - 선택한 Network를 수정한다
***************************************************************************/
void __fastcall NetworkModifyClick(TObject *Sender)
{

 if(Main->LbNetworkList->ItemIndex < 0 || Main->PrintingNetwork[Main->LbNetworkList->ItemIndex] < 0) {
   MessageDlg("Please select parent satellite", mtError, TMsgDlgButtons() << mbOK, 0);
   return;
 }


 NetworkEditor->FormInitialize();

 // 네트워크 정보를 현재 상태로 셋팅한다
 NetworkSubstitutionStandByForm(Main->PrintingNetwork[Main->LbNetworkList->ItemIndex]);
 NetworkEditor->Tag = 0;


 // 네트워크 수정 창을 연다
 NetworkEditor->ShowModal();


 // OK 버튼이 눌러졌을때의 처리
 if(NetworkEditor->Tag) {
   Main->BackupData();
   NetworkSubstitutionStandByNetwork(Main->PrintingNetwork[Main->LbNetworkList->ItemIndex]);
   PrintNetwork();

   Main->Modified = True;
 }

}


/**************************************************************************
  NetworkDeleteClick
  - 선택한 Network를 삭제한다
***************************************************************************/
void __fastcall NetworkDeleteClick(TObject *Sender)
{

 int     itTemp, itNetworkIndex = Main->PrintingNetwork[Main->LbNetworkList->ItemIndex],
         itNetworkCount, itTransponderIndex;


 if(Main->LbNetworkList->ItemIndex >= 0 && itNetworkIndex >= 0) {
   Main->BackupData();

   // 해당 Network의 Transponder를 모두 삭제
   for(itTransponderIndex = 0; itTransponderIndex < MAX_TRANSPONDER_DATA; itTransponderIndex ++)
     if(Main->Transponder_VList[itTransponderIndex].Status == DATA_OCCUPY &&
        Main->Transponder_List[itTransponderIndex].Network_Index == (U32)itNetworkIndex)
     TransponderDeleteProcess(itTransponderIndex);

   Main->LbNetworkList->SetFocus();

   for(itNetworkCount = 0; itNetworkCount < MAX_NETWORK_DATA; itNetworkCount ++)
     if(itNetworkIndex != itNetworkCount &&
        Main->Network_VList[itNetworkCount].Status == DATA_OCCUPY &&
        Main->Network_VList[itNetworkCount].Order > Main->Network_VList[itNetworkIndex].Order)
       Main->Network_VList[itNetworkCount].Order --;

   Main->Network_VList[itNetworkIndex].Status = DATA_FREE;
   Main->Network_VList[itNetworkIndex].Order  = 0;

   Main->Modified = True;
   PrintNetwork();
  } else {
   MessageDlg("Please select target satellite", mtError, TMsgDlgButtons() << mbOK, 0);
 }

}


/**************************************************************************
  NetworkListDragOver
  - 선택한 Network를 다른곳으로 옮길때 옮길 수 있는지 여부와 막대바를 표시한다
***************************************************************************/
bool __fastcall NetworkListDragOver(TObject *Sender, TObject *Source, int X, int Y)
{

 int                    itSourceIndex, itTargetIndex;
 String                 stClassName = Source->ClassName();
 int                    itDirection, itSell;
 bool                   blAccept;


 if(stClassName == "TListBox" && dynamic_cast<TControl *>(Source)->Name == "LbNetworkList" &&
    dynamic_cast<TControl *>(Sender)->Name == "LbNetworkList") {
   itSourceIndex = Main->LbNetworkList->ItemIndex;
   itTargetIndex = Main->LbNetworkList->ItemAtPos(Point(X, Y), True);
   itDirection   = itSourceIndex > itTargetIndex ? 0 : 1;
   itSell        = itTargetIndex - Main->LbNetworkList->TopIndex  + itDirection;

   if(itSourceIndex == -1 || itTargetIndex == -1) {
     blAccept                           = False;
     Main->PnNetworkInsertLine->Visible = False;
     Main->PnNetworkInsertLine->Tag     = 0;
    } else {
     blAccept                    = True;
     Main->PnNetworkInsertLine->Top     = 100 + (20 * itSell);
     if(itSourceIndex != itTargetIndex)
       Main->PnNetworkInsertLine->Visible = True;
      else
       Main->PnNetworkInsertLine->Visible = False;
   }

   if(itSell - itDirection == 0) {
     Main->PnNetworkInsertLine->Tag = -1;
    } else if(itSell >= 6 - 1) {
     Main->PnNetworkInsertLine->Tag = 1;
    } else
     Main->PnNetworkInsertLine->Tag = 0;

   return(blAccept);
 }

 return(false);

}


/**************************************************************************
  NetworkListDragDrop
  - 선택한 Network를 옮겼을때의 처리
***************************************************************************/
void __fastcall NetworkListDragDrop(TObject *Sender, TObject *Source, int X, int Y)
{

 int                    itSourceIndex, itTargetIndex, itTargetOrder;
 String                 stClassName = Source->ClassName();
 int                    itNetworkCount;


 if(stClassName == "TListBox" && dynamic_cast<TControl *>(Source)->Name == "LbNetworkList" &&
    dynamic_cast<TControl *>(Sender)->Name == "LbNetworkList") {
   itSourceIndex = Main->LbNetworkList->ItemIndex;
   itTargetIndex = Main->LbNetworkList->ItemAtPos(Point(X, Y), True);
   itTargetOrder = Main->Network_VList[Main->PrintingNetwork[itTargetIndex]].Order;

   if(itSourceIndex == -1 || itTargetIndex == -1 || itSourceIndex == itTargetIndex) {
     return;
    } else {
     Main->Modified = True;

     if(itSourceIndex > itTargetIndex) {
       Main->Network_VList[Main->PrintingNetwork[itSourceIndex]].Order = itTargetOrder;

       for(itNetworkCount = itTargetIndex; itNetworkCount < itSourceIndex; itNetworkCount ++)
         Main->Network_VList[Main->PrintingNetwork[itNetworkCount]].Order ++;
      } else {
       for(itNetworkCount = itSourceIndex; itNetworkCount <= itTargetIndex; itNetworkCount ++)
         Main->Network_VList[Main->PrintingNetwork[itNetworkCount]].Order --;

       Main->Network_VList[Main->PrintingNetwork[itSourceIndex]].Order = itTargetOrder;
     }

     Main->LbNetworkList->ItemIndex = itTargetIndex;
     PrintNetwork();
   }
 }

}


/**************************************************************************
  NetworkListSort
  - Network List를 정렬한다
***************************************************************************/
void __fastcall NetworkListSort(int itSortStandard)
{

 __int64                itSourceValue, itTargetValue, itSourceSubValue, itTargetSubValue, itTemp;
 int                    itNetworkIndex, itSourceIndex, itTargetIndex,
                        itOrderIndex = 0;
 TNetwork_Structure     nsTemp;
 bool                   blSwap = False;


 Main->BackupData();

 if(Main->HcNetworkList->Tag == itSortStandard) {
   blSwap = True;
   Main->HcNetworkList->Tag = -1;
  } else {
   Main->HcNetworkList->Tag = itSortStandard;
 }

 for(itSourceIndex = 0; itSourceIndex < MAX_NETWORK_DATA; itSourceIndex ++)
   for(itTargetIndex = itSourceIndex; itTargetIndex < MAX_NETWORK_DATA; itTargetIndex ++) {
     if(Main->Network_VList[itSourceIndex].Status == DATA_OCCUPY &&
        Main->Network_VList[itTargetIndex].Status == DATA_OCCUPY) {
       switch(itSortStandard) {
         case 0 : {
           itSourceValue    = StringToAbilityNumber(Main->Network_List[itSourceIndex].Name);
           itTargetValue    = StringToAbilityNumber(Main->Network_List[itTargetIndex].Name);

           itSourceSubValue = Main->Network_List[itSourceIndex].UserLowLocal;
           itTargetSubValue = Main->Network_List[itTargetIndex].UserLowLocal;
           break;
         }

         case 1 : {
           itSourceValue    = Main->Network_List[itSourceIndex].Config_2;
           itTargetValue    = Main->Network_List[itTargetIndex].Config_2;

           itSourceSubValue = StringToAbilityNumber(Main->Network_List[itSourceIndex].Name);
           itTargetSubValue = StringToAbilityNumber(Main->Network_List[itTargetIndex].Name);
           break;
         }

         case 2 : {
           if(Main->Network_List[itSourceIndex].Config_2 == USERFREQUENCY_IN_ITEMLIST)
             itSourceValue = Main->Network_List[itSourceIndex].UserLowLocal;
            else
             itSourceValue = NetworkEditor->CbMasterFrequency->Items->Strings[Main->Network_List[itSourceIndex].Config_2].SubString(13, 6).Trim().ToInt();

           if(Main->Network_List[itTargetIndex].Config_2 == USERFREQUENCY_IN_ITEMLIST)
             itTargetValue = Main->Network_List[itTargetIndex].UserLowLocal;
            else
             itTargetValue = NetworkEditor->CbMasterFrequency->Items->Strings[Main->Network_List[itTargetIndex].Config_2].SubString(13, 6).Trim().ToInt();

           itSourceSubValue = StringToAbilityNumber(Main->Network_List[itSourceIndex].Name);
           itTargetSubValue = StringToAbilityNumber(Main->Network_List[itTargetIndex].Name);
           break;
         }

         case 3 : {
           itSourceValue    = NetworkTransponderNum(itSourceIndex);
           itTargetValue    = NetworkTransponderNum(itTargetIndex);

           itSourceSubValue = StringToAbilityNumber(Main->Network_List[itSourceIndex].Name);
           itTargetSubValue = StringToAbilityNumber(Main->Network_List[itTargetIndex].Name);
           break;
         }
       }

       if(blSwap) {
         itTemp = itSourceValue;
         itSourceValue = itTargetValue;
         itTargetValue = itTemp;

         itTemp = itSourceSubValue;
         itSourceSubValue = itTargetSubValue;
         itTargetSubValue = itTemp;
       }

       if(itSourceValue > itTargetValue || (itSourceValue == itTargetValue && itSourceSubValue > itTargetSubValue)) {
         ParentNetworkChange(itSourceIndex, itTargetIndex);

         nsTemp = Main->Network_List[itSourceIndex];
         Main->Network_List[itSourceIndex] = Main->Network_List[itTargetIndex];
         Main->Network_List[itTargetIndex] = nsTemp;
       }
     }
   }

 for(itNetworkIndex = 0; itNetworkIndex < MAX_NETWORK_DATA; itNetworkIndex ++)
   if(Main->Network_VList[itNetworkIndex].Status == DATA_OCCUPY)
     Main->Network_VList[itNetworkIndex].Order = ++ itOrderIndex;


 Main->Modified = True;
 PrintNetwork();

}

#pragma package(smart_init)
