#include "ftpro.h"
#include "cs_strtok.h"
BEGIN_EVENT_TABLE(RemoteList,wxListCtrl)
  EVT_RIGHT_DOWN(RemoteList::OnRightDown)
END_EVENT_TABLE()

void RemoteList::OnRightDown(wxMouseEvent &event)
{
  MyPopupMenu menu("Remote");
  menu.Append( ID_REMOTE_NEW_DIR_RC, "New Directory", "" );
  menu.Append( ID_REMOVE_DIR_RC, "Remove", "" );
  menu.AppendSeparator();
  menu.Append( ID_REMOTE_GET_RC, "Get", "" );
  menu.AppendSeparator();
  menu.Append( ID_REMOTE_PWD_RC, "PWD", "" );
  menu.Append( ID_REMOTE_REFRESH_RC, "Refresh","");
  //  menu.Append( ID_REMOTE_OWNER_RC, "Owner");
  menu.Append( ID_REMOTE_LIST_RC, "List","");
  menu.AppendSeparator();
  menu.Append( ID_REMOTE_RO_RC, "Open in Editor", "" );
  menu.Append( ID_REMOTE_PO_RC, "Open In Programmers Editor", "" );
  PopupMenu(&menu,event.GetX(),event.GetY());

}

void HarborDialog::OnRemoteNewDir()
{
  wxString dir = wxGetTextFromUser("What do you want to call the new directory ?","New directory");
  if (dir == "")
    return;
  if (!(GetFTP().Mkdir(dir.c_str())))
    {
      wxMessageDialog dialog(this,"Could not make directory, do you have correct permissions?","Error: Could not make directory!" , wxOK | wxICON_ERROR);
      dialog.ShowModal();
    }
  GetRemoteFiles();
  
}


void HarborDialog::OnRemoteGetMany()
{
  int sel_type;
  wxString file;
  long item = -1;
  long size = 0;
    for ( ;; )
    {
      item = HarborDialog::remote_list->GetNextItem(item,
                                                    wxLIST_NEXT_ALL,
                                                    wxLIST_STATE_SELECTED);
        if ( item == -1 )
            break;
        sel_type = HarborDialog::remote_list->GetItemData(item);
        
        //        if (sel_type != 0)
        if (1)
          {
            wxProgressDialog PD("Downloading...Please wait","Downloading");
            file = HarborDialog::remote_list->GetItemText(item);
            if (!(GetFTP().Size(file.c_str(),size)))
              {
                wxMessageDialog dialog(this, "Could not Get Size!", "Error: File download", wxOK |wxICON_ERROR);
                dialog.ShowModal();
              }   
            if (!(GetFTP().GetFile(file.c_str(), file.c_str(), size, PD)))
              {
                wxMessageDialog dialog(this, "Could not download file!"," ",wxOK);
                dialog.ShowModal();
              }
          }
        
    }
    GetLocalFiles(wxGetCwd());
}


void HarborDialog::OnRemoteRemove()
{
  int sel, sel_type;
  wxString file;
long size;

  string owner;

  sel = GetSelected(HarborDialog::remote_list);
  sel_type = HarborDialog::remote_list->GetItemData(sel);
  file = HarborDialog::remote_list->GetItemText(sel);

  if (sel_type == 0)
    {
      if (!(GetFTP().Rmdir(file.c_str())))
        {
          wxMessageDialog dialog(this, "Could not remove directory, do you have permissions ?" ,"Error: Could not remove directory",wxOK);
          dialog.ShowModal();
          return;
        }
    }
  else
    {
      if (!(GetFTP().Rm(file.c_str())))
        {
          wxMessageDialog dialog(this, "Error Could not remove" ,"Error: Could not remove file",wxOK);
          dialog.ShowModal();
          return;
        }
    }
  GetRemoteFiles();

}

void HarborDialog::GetRemoteFiles()
{
  string listing, temp;
  vector<wxString> dir_v;
  vector<wxString> file_v[3];
  vector<wxString> size_v;
  wxString name, Types;
  int index = 0, k = 0,entries = 0, pause = 0, icon_type = 10, c = 0;

  listing.erase();
  if (!(GetFTP().Ls(listing)))
    {
      wxMessageDialog dialog(this, "Could not get files, aborting...","Error: Couldnt List", wxOK);
      dialog.ShowModal();
    }


  if (listing.length() <= 0)
    {
      // if its empty, we erase everything and then bail out
      HarborDialog::remote_list->DeleteAllItems();      
      return;
    }

  stringTok one(&listing, "\n");
  one.NextToken();

  while (one.HasMoreTokens())
    {

      temp = one.NextToken();
      stringTok two(&temp, " ");
        
      if (temp[0] == 'd')
        {
          while (two.HasMoreTokens())
            {
              name = (two.NextToken()).c_str();
              if (name[name.Length() - 1] == '\r')
                name[name.Length() -1 ] = '\0';
              //            dir_array[i++] = name;
            }
          dir_v.push_back(name);
        }
        
      else if (temp[0] == '-')
        {

          while (two.HasMoreTokens())
            {
              c++;
              name = (two.NextToken()).c_str();
              if (name[name.Length() - 1] == '\r')
                name[name.Length() -1 ] = '\0';                                
              if (c == 3 || c == 5 || c == 9)
                file_v[k++].push_back(name);

            }
          c = 0;
          k = 0;
        }
      else if (temp[0] == '2')
        break;
      else
        continue;
        
    }

  HarborDialog::remote_list->DeleteAllItems();


   for (int j = 0;j < dir_v.size();j++)
    {

      HarborDialog::remote_list->InsertItem(index, dir_v[j],0);
      HarborDialog::remote_list->SetItem(index,2,"Dir");
      HarborDialog::remote_list->SetItem(index,3,"4096");
      HarborDialog::remote_list->SetItemData(index,0);
      index++;
    }
  for (k = 0;k < file_v[2].size();k++)
    {
     
      if (file_v[2][k].AfterLast('.').IsSameAs("txt"))
        {
          Types = "Text";
          icon_type = 1;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("doc"))
        {
          Types = "doc";
          icon_type = 2;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("exe"))
        {
          Types = "exe";
          icon_type = 3;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("mp3") || file_v[2][k].AfterLast('.').IsSameAs("wav"))
        {
          Types = "music";
          icon_type = 4;
        }
      else if ((file_v[2][k].AfterLast('.').IsSameAs("mpeg")) || (file_v[2][k].AfterLast('.').IsSameAs("avi")) ||
               (file_v[2][k].AfterLast('.').IsSameAs("asf")) ||  (file_v[2][k].AfterLast('.').IsSameAs("ra")) ||
               (file_v[2][k].AfterLast('.').IsSameAs("mpg")) ||  (file_v[2][k].AfterLast('.').IsSameAs("mov")))
        {
          Types = "movie";
          icon_type = 5;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("gif") || file_v[2][k].AfterLast('.').IsSameAs("jpg") ||
               (file_v[2][k].AfterLast('.').IsSameAs("jpeg")) || (file_v[2][k].AfterLast('.').IsSameAs("bmp")))
        {
          Types = "picture";
          icon_type = 6;
        }
      else if (file_v[2][k].CmpNoCase("readme") == 0)
        {
          Types = "Readme";
          icon_type = 7;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("bat") || file_v[2][k].AfterLast('.').IsSameAs("sys") ||
               file_v[2][k].AfterLast('.').IsSameAs("dll") || file_v[2][k].AfterLast('.').IsSameAs("la"))
        {
          Types = "System File";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("zip") || file_v[2][k].AfterLast('.').IsSameAs("rpm"))
        {
          Types = "zip";
          icon_type = 8;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("tgz") || file_v[2][k].AfterLast('.').IsSameAs("gz") ||
               file_v[2][k].AfterLast('.').IsSameAs("bz2"))
        {
          Types = "tgz";
          icon_type = 9;
        }
      else if (file_v[2][k].AfterLast('.').Contains("cpp") || (file_v[2][k].AfterLast('.').Contains("hpp")))
        {
          Types = "C++";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs('c') || (file_v[2][k].AfterLast('.').IsSameAs('h')))
        {
          Types = "C";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs('o'))
        {
          Types = "Object File";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("pl") || file_v[2][k].AfterLast('.').IsSameAs("cgi") ||
               file_v[2][k].AfterLast('.').IsSameAs("pm"))
        {
          Types = "Perl";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').Contains("html"))
        {
          Types = "HTML";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("py"))
        {
          Types = "Python!";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').Contains("php"))
        {
          Types = "PHP";
          icon_type = 10;
        }
      else if (file_v[2][k].Contains("Makefile"))
        {
          Types = "Makefile";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("rc"))
        {
          Types = "Windows Resource";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("el"))
        {
          Types = "Elisp";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("cl"))
        {
          Types = "Common Lisp";
          icon_type = 10;
        }

      else if (file_v[2][k].AfterLast('.').IsSameAs("java") || file_v[2][k].AfterLast('.').IsSameAs("class"))
        {
          Types = "Java";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("rb"))
        {
          Types = "Ruby";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("m3"))
        {
          Types = "Modula3";
          icon_type = 10;
        }
      else if (file_v[2][k].AfterLast('.').IsSameAs("ss") || file_v[2][k].AfterLast('.').IsSameAs("scm"))
        {
          Types = "Scheme";
          icon_type = 10;
        }
      else if (file_v[2][k][file_v[2][k].Length() - 1] == '~')
        {
          Types = "Emacs autosave";
          icon_type = 10;
        }
      else
        {
          Types = "Unkown";
          icon_type = 2;
        }
      //      wxMessageDialog dialog(this, " "," ",wxOK);

      // these are needed because for super huge files, it just crashes, with caught signal SIGTRAP ?
//       if (k % 200)
//         Sleep(20);
      HarborDialog::remote_list->InsertItem(index, file_v[2][k],icon_type);
      HarborDialog::remote_list->SetItem(index,1,file_v[0][k]);
      HarborDialog::remote_list->SetItem(index,2,Types);
      HarborDialog::remote_list->SetItem(index,3,file_v[1][k]);
      HarborDialog::remote_list->SetItemData(index,icon_type);
      index++;
    }



}

void HarborDialog::OnRemotePWDRC()
{
  string pwd;
  try
    {
      pwd = GetFTP().Pwd();
    }
  catch (FTP::InvalidCommand)
    {
      wxMessageDialog dialog(this, "Unable to complete request","Error: ",wxOK | wxICON_ERROR);
      dialog.ShowModal();
      return;
    }
  wxMessageDialog dialog(this, pwd.c_str(),"PWD",wxOK);
  dialog.ShowModal();

}

void HarborDialog::OnRemoteStatus()
{
  int sel, sel_type;
  wxString file;
  long size;

  string owner;

  sel = GetSelected(HarborDialog::remote_list);
  sel_type = HarborDialog::remote_list->GetItemData(sel);
  file = HarborDialog::remote_list->GetItemText(sel);  

  if (!(GetFTP().Owner(file.c_str(), owner)))
    {
      wxMessageDialog dialog(this, "Couldnt complete request!","Error: Owner",wxOK | wxICON_ERROR);
      dialog.ShowModal();
      return;
    }
  
  wxMessageDialog dialog(this, owner.c_str(),"Owner" ,wxOK);
  dialog.ShowModal();

}


void HarborDialog::OnRemoteCdup( wxCommandEvent &event )
{

    wxBeginBusyCursor();
    if (!(GetFTP().Cdup()))
    {
        wxMessageDialog dialog(this, "Could not change directories...aborting", "Error: Directory", wxOK);
        dialog.ShowModal();
        return;
    }

    HarborDialog::remote_list->DeleteAllItems();

    GetRemoteFiles();

    wxString pwd = GetRemoteDir().BeforeLast('/');
    wxString ppwd = GetPreviousRemoteDir().BeforeLast('/');
    HarborDialog::remote_pwd_cb->Append(pwd);
    HarborDialog::remote_pwd_cb->SetValue(pwd);

    SetRemoteDir(pwd);
    SetPreviousRemoteDir(ppwd);
    wxEndBusyCursor();
    
}

void HarborDialog::OnRemoteHome( wxCommandEvent &event )
{
  wxBeginBusyCursor();
  if (!(GetFTP().Cd("/")))
    {
      wxMessageDialog dialog(this, " "," ",wxOK);
      dialog.ShowModal();
      return;
    }
  SetRemoteDir("");
  SetPreviousRemoteDir("");
  GetRemoteFiles();
  wxEndBusyCursor();

  HarborDialog::remote_pwd_cb->Append("/");
  HarborDialog::remote_pwd_cb->SetValue("/");

}



void HarborDialog::OnRemotePWD( wxCommandEvent &event )
{

  if (!(GetFTP().Cd(remote_pwd_cb->GetStringSelection().c_str())))
    {
      wxMessageDialog dialog(this, "Cant change to that directory,...aborting",remote_pwd_cb->GetValue(),wxOK);
      dialog.ShowModal();
    }    
  GetRemoteFiles();
  UpdateRemotePWD();
}

void HarborDialog::OnRemoteBeginDrag( wxListEvent &event )
{
    
}

void HarborDialog::OnRemoteRightClicked( wxListEvent &event )
{
    
}

void HarborDialog::OnRemoteActivated( wxListEvent &event )
{
  int sel, sel_type;
  
  wxString file;
  wxString cwd;
  long size;


  cwd= wxGetCwd() + "\\";


  sel = GetSelected(HarborDialog::remote_list);
  sel_type = HarborDialog::remote_list->GetItemData(sel);
  file = HarborDialog::remote_list->GetItemText(sel);

  switch (sel_type)
    {
    case 0:
      {
        wxBeginBusyCursor();

        if (!(GetFTP().Cd(file.c_str())))
          {
            wxMessageDialog dialog(this, "Couldn't change to " + file + ".  Do you have correct permissions?","Error: Couldnt change directories",wxOK | wxICON_ERROR);
            dialog.ShowModal();
            return;
          }



        GetRemoteFiles();
        wxEndBusyCursor();

        //set the previous to current, and then the current
        SetPreviousRemoteDir(GetRemoteDir());
        SetRemoteDir(GetPreviousRemoteDir() + "/" + file.c_str());

        UpdateRemotePWD();


        break;
      }
    default:
      {
        wxBeginBusyCursor();
        wxProgressDialog PD("Downloading...Please wait", "Downloading");

          if (!(GetFTP().Size(file.c_str(),size)))
          {
            wxMessageDialog dialog(this, "Could not Get Size!", "Error: File download", wxOK |wxICON_ERROR);
            dialog.ShowModal();
          }   
        if (!(GetFTP().GetFile(file.c_str(), file.c_str(), size, PD)))
          {
            wxMessageDialog dialog(this, "Could not download file!", "Error: File download", wxOK |wxICON_ERROR);
            dialog.ShowModal();
            wxEndBusyCursor();
            return;
          }
        wxEndBusyCursor();
        GetLocalFiles(wxGetCwd());
        break;
      }
    }

}

void HarborDialog::UpdateRemotePWD()
{
  remote_pwd_cb->Append(GetRemoteDir());
  remote_pwd_cb->SetValue(GetRemoteDir());

}

void HarborDialog::OnRemoteRegularOpen()
{

int sel, sel_type;
  
  wxString file;
  wxString cwd;
  long size;

  sel = GetSelected(HarborDialog::remote_list);
  sel_type = HarborDialog::remote_list->GetItemData(sel);
  file = HarborDialog::remote_list->GetItemText(sel);

  wxBeginBusyCursor();
  wxProgressDialog PD("Downloading...Please wait", "Downloading");
  
  if (!(GetFTP().Size(file.c_str(),size)))
    {
      wxMessageDialog dialog(this, "Could not Get Size!", "Error: File download", wxOK |wxICON_ERROR);
      dialog.ShowModal();
    }   
  if (!(GetFTP().GetFile(file.c_str(), file.c_str(), size, PD)))
    {
      wxMessageDialog dialog(this, "Could not download file!", "Error: File download", wxOK |wxICON_ERROR);
      dialog.ShowModal();
            wxEndBusyCursor();
            return;
    }
  wxEndBusyCursor();

  wxString temp = GetRegularEditor() + " \"" + wxGetCwd() + "\\" +  file + "\"";
  if (!(wxExecute(temp)))
    {
      wxMessageDialog dialog(this, "Could not open Programming Editor, aborting...", GetProgrammingEditor(), wxOK | wxICON_ERROR);
      dialog.ShowModal();
    }

  wxMessageDialog upload(this, "Click yes when you are done editing to save and upload\nNo to cancel","Save and upload",wxYES_NO | wxICON_INFORMATION);
  if (upload.ShowModal() == wxID_YES)
    {
      wxProgressDialog PU("Uploading...Please wait","Uploading");
      if (!(GetFTP().PutFile(file.c_str(), PU)))
        {
          wxMessageDialog dialog(this, "Error in uploading, do you have the right permissions ?","Error in uploadin",wxOK);
          dialog.ShowModal();
        }
    }
  if (!(wxRemoveFile(file.c_str())))
    {
      wxMessageDialog dialog(this, "Could not delete file, is your editor still open ?","Error: Deleting file",wxOK);
      dialog.ShowModal();
    }
    
  GetLocalFiles(wxGetCwd());
  return;
}

void HarborDialog::OnRemoteProgrammersOpen()
{
int sel, sel_type;
  
  wxString file;
  wxString cwd;
  long size;

  sel = GetSelected(HarborDialog::remote_list);
  sel_type = HarborDialog::remote_list->GetItemData(sel);
  file = HarborDialog::remote_list->GetItemText(sel);

  wxBeginBusyCursor();
  wxProgressDialog PD("Downloading...Please wait", "Downloading");
  
  if (!(GetFTP().Size(file.c_str(),size)))
    {
      wxMessageDialog dialog(this, "Could not Get Size!", "Error: File download", wxOK |wxICON_ERROR);
      dialog.ShowModal();
    }   
  if (!(GetFTP().GetFile(file.c_str(), file.c_str() , size, PD)))
    {
      wxMessageDialog dialog(this, "Could not download file!", "Error: File download", wxOK |wxICON_ERROR);
      dialog.ShowModal();
            wxEndBusyCursor();
            return;
    }
  wxEndBusyCursor();

  wxString temp = GetProgrammingEditor() + " \"" + wxGetCwd() + "\\" + file + "\"";
  if (!(wxExecute(temp)))
    {
      wxMessageDialog dialog(this, "Could not open Programming Editor, aborting...", GetProgrammingEditor(), wxOK | wxICON_ERROR);
      dialog.ShowModal();
    }

  wxMessageDialog upload(this, "Click yes when you are done editing to save and upload\nNo to cancel","Save and upload",wxYES_NO | wxICON_INFORMATION);
  if (upload.ShowModal() == wxID_YES)
    {
      wxProgressDialog PU("Uploading...Please wait","Uploading");
      if (!(GetFTP().PutFile(file.c_str(), PU)))
        {
          wxMessageDialog dialog(this, "Error in uploading, do you have the right permissions ?","Error in uploadin",wxOK);
          dialog.ShowModal();
        }
    }
  else
    {
      if (!(wxRemoveFile(file)))
        {
          wxMessageDialog dialog(this, "Please close the editor so that we may remove the file","Error",wxOK | wxICON_ERROR);
          dialog.ShowModal();
          wxRemoveFile(file);
        }
    }
  GetLocalFiles(wxGetCwd());
}


void HarborDialog::OnRemoteList()
{
  string listing;
  if (!(GetFTP().Ls(listing)))
    {
      wxMessageDialog dialog(this, " "," ",wxOK);
      dialog.ShowModal();
    }
  
  wxMessageDialog dialog(this, listing.c_str(),"Listing" ,wxOK | wxICON_INFORMATION);
  dialog.ShowModal();
}

void HarborDialog::OnRemoteRefresh()
{
  GetRemoteFiles();
}

void HarborDialog::OnRemoteOwner()
{
  
  int sel, sel_type;
  wxString file;
  string owner;
  sel = GetSelected(HarborDialog::remote_list);
  file = HarborDialog::remote_list->GetItemText(sel);

  wxBeginBusyCursor();
  if (!(GetFTP().Owner(file.c_str(), owner)))
    {
      wxMessageDialog dialog(this, "Error in getting owner!","Error: Getting info",wxOK | wxICON_ERROR);
      dialog.ShowModal();
      return;
    }
  wxMessageDialog dialog(this, owner.c_str(),"Owner info",wxOK | wxICON_INFORMATION);
  dialog.ShowModal();
}