Subversion Repositories spk

Rev

Rev 273 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include "../StdAfx.h"
#include "PackageForm.h"
#include "InputBox.h"
#include "Form1.h"
#include "AddWareText.h"
#include "AddCockpit.h"
#include "SaveDialog.h"
#include "AddGlobal.h"

#include <Package/InstallText.h>

namespace Creator {
        void PackageForm::_init() 
        {
                this->LabelShipWarning->Visible = false;
                this->TextExactVersion->Visible = false;
                this->DoToolTips();

                this->ListDep->LargeImageList = this->imageList1;
                this->ListDep->SmallImageList = this->imageList1;
                this->listGlobals->LargeImageList = this->imageList1;
                this->listGlobals->SmallImageList = this->imageList1;

                m_iFormType = FORMTYPE_SINGLE;
                m_pDisplayFile = NULL;

                this->NumTextID->Visible = false;

                m_iSelectedGame = -1;

                this->Closing += gcnew CancelEventHandler(this, &PackageForm::PackageForm_Closing);

                _pPackages = new CPackages();
                _pPackages->startup(L".", _WS(IO::Path::GetTempPath()), _WS(Environment::GetFolderPath(Environment::SpecialFolder::Personal)));
                m_pPackage = NULL;
                m_pTypeList = new Utils::WStringList;

                this->ComboShipPart->SelectedIndex = 0;

                m_bLoading = false;
        }

        PackageForm::~PackageForm()
        {
                if (components)
                        delete components;

                delete m_pTypeList;
                if (m_pPackage)
                        delete m_pPackage;
                if (_pPackages)
                        delete _pPackages;
        }

        void PackageForm::SetImageLists(ImageList ^smallList, ImageList ^largeList, ImageList ^gameList, ImageList ^fileList)
        {
                BaseForm::SetImageLists(smallList, largeList, gameList);

                this->ListGames->SmallImageList = this->imageListGames;
                this->ListGames->LargeImageList = this->imageListGames;
                this->ListNames->SmallImageList = this->imageListSmall;
                this->ListMirrors->SmallImageList = this->imageListSmall;
                this->ListWares->SmallImageList = this->imageListSmall;
                this->ListWareText->SmallImageList = this->imageListSmall;
                this->ListShipText->SmallImageList = this->imageListSmall;
                this->ListShipPart->SmallImageList = this->imageListSmall;

                this->ListNames->LargeImageList = this->imageListLarge;
                this->ListMirrors->LargeImageList = this->imageListLarge;
                this->ListWares->LargeImageList = this->imageListLarge;
                this->ListWareText->LargeImageList = this->imageListLarge;
                this->ListShipText->LargeImageList = this->imageListLarge;
                this->ListShipPart->LargeImageList = this->imageListLarge;

                this->ButGame->ImageList = this->imageListGames;

                this->imageListFiles = fileList;
                this->ListFiles->LargeImageList = this->imageListFiles;
                this->ListFiles->SmallImageList = this->imageListFiles;

                this->Setup();
        }
           
        bool PackageForm::LoadPackage(CBaseFile *base, System::String ^filename)
        {
                m_sFilename = filename;

                if ( !base )
                {
                        int error;
                        m_pPackage = m_pP->openPackage(_WS(filename), &error);
                        if ( !m_pPackage )
                                return false;
                }
                else
                        m_pPackage = base;
                
                m_pPackage->adjustChanged(false);
                m_pPackage->updateSigned(true);
                this->UpdateChanged();
                m_bLoading = true;

                if ( m_pPackage->AnyFileType(FILETYPE_ADVERT) )
                {
                        for ( C_File *f = m_pPackage->GetFirstFile(FILETYPE_ADVERT); f; f = m_pPackage->GetNextFile(f) )
                        {
                                f->setFullDir(_WS(System::IO::Path::GetTempPath()));
                                long size;
                                unsigned char *data = f->UncompressData(&size, 0);
                                if ( data && size )
                                {
                                        if ( f->writeFilePointer(data, size) )
                                        {
                                                if ( !m_pDisplayFile )
                                                        m_pDisplayFile = f;
                                        }

                                        if ( f->GetCompressionType() != SPKCOMPRESS_NONE )
                                                delete data;
                                }
                        }
                }

                if ( m_pPackage->icon() )
                {
                        C_File *f = m_pPackage->icon();
                        f->setFilename(_WS(System::IO::Path::GetTempPath()) + L"/package_icon." + m_pPackage->iconExt());
                        f->setFullDir(_WS(System::IO::Path::GetTempPath()));
                        long size;
                        unsigned char *data = f->UncompressData(&size, 0);
                        if ( data && size )
                        {
                                f->writeFilePointer(data, size);
                                if ( f->GetCompressionType() != SPKCOMPRESS_NONE )
                                        delete data;
                        }
                }

                this->RadioInstallBefore->Checked = true;
                this->RadioInstallAfter->Checked = false;
                this->RadioUninstallAfter->Checked = false;
                this->RadioUninstallBefore->Checked = false;
                this->UpdateView();

                m_pPackage->adjustChanged(false);

                m_bLoading = false;

                return true;
        }

        void PackageForm::DoToolTips()
        {
                //tooltip1 for any controls with text to display
                this->toolTip1->SetToolTip(this->RadioTypeUpdate, "This allows you to create a small package to update an already installed one with new files.\nIn the Dependacy section you can set the minimum version required to install.\nAny mod files only need to contain the files you want to update, they will be added into the existing mod file when installed");
                this->toolTip1->SetToolTip(this->RadioTypeStart, "This allows you to create a custom start in the old format\nWhen installed, it will use the added initplayer script to create the maps and jobs file automatically\nThis allows it to always use the most up to date map automatically, so you only need to make changes to the script file\nIf set to use another mod, it'll use the map from the mod instead of the games one");
                this->toolTip1->SetToolTip(this->RadioTypePatch, "This allows you to create patchs to your mod files\nWhen installing, any files in the patch mod will overright the base mod files, allowing you to create different patchs allowing users to customise your mod without having to have seperate mod installs\nWhen the patch is uninstalled, any changed files will be restored back to the normal ones");
                this->toolTip1->SetToolTip(this->CheckShipID, "This allows you to replaing an existing ship when you install\nNormally, the ship is simply added into the game, at the end of the ships file, when set to replace, it will replace the ship with the same ship id.\nThis allows you to create an update to an existing ship without having to have both in the game");
                this->toolTip1->SetToolTip(this->groupBox3, "This allows you to set the parent package\nThis will need to be installed as well, unlike depencies, the child/parent packages are linked to each other\nThis allows you to release updates or addons for a certain package, one that will only work with the parent package");
                this->toolTip1->SetToolTip(this->ButFromFile, "This will read the details from an existing file\nWhen selected, you will be prompted to select a saved package file.\nThe package name and author is then read from the package and automatically filled in so you know its entered correctly");
                this->toolTip1->SetToolTip(this->RadioInstallBefore, "This is a message you can give to the user when they install your package\nThis will come before the installation starts and allows you to display information or warnings about the package they are about to install to help them decide if they want to continue installing or not");
                this->toolTip1->SetToolTip(this->RadioInstallAfter, "This message is displayed to the user once the package has been installed\nThis is usually used to give the user information about your package, like how to start using it in game, or important information before they start using it, etc");
                this->toolTip1->SetToolTip(this->RadioUninstallBefore, "This message is displayed when the user attempts to uninstall your package\nThis can be used to give the user instruction on what else they might need to do to uninstall, ie if theres something they need to do ingame first before removing the package");
                this->toolTip1->SetToolTip(this->RadioUninstallAfter, "This message is displayed after the user has uninstalled your package\nThis can give them information about anything else they might need to do to remove the package, ie to allow the uninstall scripts to function to remove anything from thier game");
                this->toolTip1->SetToolTip(this->GroupEase, "This is a rating allowing the user to see how easy it is to use the script\nThe ratings are displayed when installing the package and are from 1 to 5, 5 being easy to use, 1 being hard\nClicking on the stars will adjust the rating");
                this->toolTip1->SetToolTip(this->GroupChange, "This is a rating allowing the user to see how much the package changes the game\nThe ratings are displayed when installing the package and are from 1 to 5, 5 being alot of change, 1 being very little\nClicking on the stars will adjust the rating");
                this->toolTip1->SetToolTip(this->GroupRec, "This is a rating allowing the user to see how much you recommended this package\nThe ratings are displayed when installing the package and are from 1 to 5, 5 highly recommended\nClicking on the stars will adjust the rating");

                // controls that need custom title texts using tags
                this->ComboPluginType->Tag = "Plugin Type";
                this->toolTip2->SetToolTip(this->ComboPluginType, "The plugin type is used to display roughly what type the plugin comes under, this is displayed during installation\nNormal = Just a normal package\nStable = A stable or final release of a package\nExperimental = Potentinally unstable package\nCheat = Considered to be a cheat, ie breaks game balance\nMod = A Mod, can only run 1 at a time and not compatable with other mods");
        }

        void PackageForm::UpdateScriptType()
        {
                if ( this->ComboType->SelectedIndex == CSpkFile::SCRIPTTYPE_CUSTOM )
                {
                        this->TextCustomType->Visible = true;
                        this->ComboType->Dock = Windows::Forms::DockStyle::Left;
                        if ( !m_bLoading )
                                ((CSpkFile *)m_pPackage)->setScriptType(_WS(this->TextCustomType->Text));
                 }
                 else
                 {
                         this->TextCustomType->Visible = false;
                         this->ComboType->Dock = Windows::Forms::DockStyle::Fill;
                 }
        }
        void PackageForm::UpdateText()
        {
                const SPK::Package::CInstallText *pText = NULL;

                this->TextText->Tag = 1;
                if ( this->RadioInstallAfter->Checked || this->RadioInstallBefore->Checked )
                        pText = m_pPackage->installText();
                else if ( this->RadioUninstallAfter->Checked || this->RadioUninstallBefore->Checked )
                        pText = m_pPackage->uninstallText();
                else
                {
                        this->ListLang->Enabled = false;
                        this->ButTextAdd->Enabled = false;
                        this->UpdateTextLang();
                        return;
                }

                this->ListLang->Enabled = true;
                this->ButTextAdd->Enabled = true;

                int selected = this->ListLang->SelectedIndex;
                if ( selected >= 1 )    selected = Convert::ToInt32(this->ListLang->Text);
                else                                    selected = -1;

                this->ListLang->Items->Clear();
                this->ListLang->Items->Add("- Default -");

                // add languages
                for ( unsigned int i = 0; i < pText->count(); i++ ) {
                        int iLang = pText->language(i);
                        if ( iLang <= 0 ) continue;
                        this->ListLang->Items->Add(System::Convert::ToString(iLang));
                }

                if ( selected == -1 )
                        this->ListLang->SelectedIndex = 0;
                else
                        this->ListLang->Text = Convert::ToString(selected);

                if ( this->ListLang->SelectedIndex == -1 )
                        this->ListLang->SelectedIndex = 0;

                this->UpdateTextLang();
        }

        void PackageForm::UpdateTextLang()
        {
                this->TextText->Tag = 1;
                this->TextText->Enabled = false;
                this->TextText->Text = "";

                if ( this->ListLang->SelectedIndex >= 0 )
                {
                        int lang = _WS(this->ListLang->Text).toInt();
                        Utils::WString desc;
                        if ( this->RadioInstallAfter->Checked )                 desc = m_pPackage->installText(lang, false, false);
                        else if ( this->RadioInstallBefore->Checked )   desc = m_pPackage->installText(lang, true, false);
                        else if ( this->RadioUninstallAfter->Checked )  desc = m_pPackage->uninstallText(lang, false, false);
                        else if ( this->RadioUninstallBefore->Checked ) desc = m_pPackage->uninstallText(lang, true, false);

                        this->TextText->Text = _US(desc);
                        this->TextText->Enabled = true;
                }

                this->ButTextDel->Enabled = false;
                if ( this->ListLang->SelectedIndex >= 1 )
                        this->ButTextDel->Enabled = true;

                this->TextText->Tag = nullptr;
        }

        void PackageForm::UpdateWares()
        {
                CSpkFile *spk = (CSpkFile *)m_pPackage;

                this->ListWares->Items->Clear();
                for ( SWares *w = spk->GetWaresList()->First(); w; w = spk->GetWaresList()->Next() )
                {
                        ListViewItem ^item = gcnew ListViewItem(_US(w->sID));
                        switch ( tolower(w->cType) )
                        {
                                case 'b':
                                        item->SubItems->Add("Bio");
                                        break;
                                case 'e':
                                        item->SubItems->Add("Energy");
                                        break;
                                case 'f':
                                        item->SubItems->Add("Food");
                                        break;
                                case 't':
                                        item->SubItems->Add("Tech");
                                        break;
                                case 'm':
                                        item->SubItems->Add("Mineral");
                                        break;
                                default:
                                        item->SubItems->Add("Other");
                        }
                        item->SubItems->Add(System::Convert::ToString(w->iPrice));
                        switch ( w->iSize )
                        {
                                case 0:
                                        item->SubItems->Add("Tiny Containers");
                                        break;
                                case 1:
                                        item->SubItems->Add("Small Containers (S)");
                                        break;
                                case 2:
                                        item->SubItems->Add("Medium Containers (M)");
                                        break;
                                case 3:
                                        item->SubItems->Add("Large Containers (L)");
                                        break;
                                case 4:
                                        item->SubItems->Add("Extra Large Containers (XL)");
                                        break;
                                case 5:
                                        item->SubItems->Add("Station Containers (ST)");
                                        break;
                                default:
                                        item->SubItems->Add("Other Containers");
                        }

                        item->SubItems->Add(System::Convert::ToString(w->iVolumn));
                        item->SubItems->Add(System::Convert::ToString(w->iNotority));

                        if ( w->iTextPage > 0 && w->iTextID > 0 )
                                item->SubItems->Add(System::Convert::ToString(w->iTextPage) + ", " + System::Convert::ToString(w->iTextID));
                        item->ImageIndex = 2;
                        this->ListWares->Items->Add(item);
                }
                this->ListWares->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);

                this->UpdateWareText();
                m_pPackage->updateSigned(false);
                this->UpdateChanged();
        }

        void PackageForm::UpdateWareText()
        {
                this->ListWareText->Items->Clear();
                this->splitContainer1->Panel2Collapsed = true;

                if ( this->ListWares->SelectedItems->Count )
                {
                        SWares *w = ((CSpkFile *)m_pPackage)->findWare(_WS(this->ListWares->SelectedItems[0]->Text));
                        if ( w )
                        {
                                if ( w->iTextPage <= 0 && w->iTextID <= 0 )
                                {                       
                                        this->ListWareText->Items->Clear();
                                        this->splitContainer1->Panel2Collapsed = false;
                                        for ( SWaresText *wt = w->lText.First(); wt; wt = w->lText.Next() )
                                        {
                                                ListViewItem ^item = gcnew ListViewItem(System::Convert::ToString(wt->iLang));
                                                item->ImageIndex = 0;
                                                item->SubItems->Add(_US(wt->sName));
                                                item->SubItems->Add(_US(wt->sDesc));
                                                this->ListWareText->Items->Add(item);
                                        }
                                }
                        }
                }
        }

        void PackageForm::UpdateView()
        {
                m_bLoading = true;

                System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(PackageForm::typeid));

                this->LabelShipWarning->Visible = false;
                this->TextName->Text = _US(m_pPackage->name());
                this->TextAuthor->Text = _US(m_pPackage->author());
                this->TextVersion->Text = _US(m_pPackage->version());
                Utils::WString desc = m_pPackage->description();
                desc = desc.findReplace(L"<br>", L"\n");
                desc = desc.findReplace(L"<newline>", L"\n");
                desc = desc.stripHtml();
                this->TextDesc->Text = _US(desc);

                if ( m_pPackage->GetType() == TYPE_XSP )
                {
                        CXspFile *xsp = (CXspFile *)m_pPackage;
                        this->TextShipID->Text = _US(xsp->shipID());
                        this->PanelShip->Show();
                        this->LabelShipWarning->Visible = true;
                        this->groupBox6->Visible = false;

                        this->TextShipData->Text = _US(xsp->shipData());

                        this->CheckShipID->Checked = xsp->IsExistingShip();
                        this->CheckExistingText->Checked = (xsp->GetOriginalDescription()) ? true : false;
                        if ( xsp->GetOriginalDescription() )
                                this->NumTextID->Value = xsp->GetOriginalDescription();

                        // shipyards
                        this->CheckSYArgon->Checked = xsp->isShipyard(ShipyardRace::Argon);
                        this->CheckSYBoron->Checked = xsp->isShipyard(ShipyardRace::Boron);
                        this->CheckSYTeladi->Checked = xsp->isShipyard(ShipyardRace::Teladi);
                        this->CheckSYParanid->Checked = xsp->isShipyard(ShipyardRace::Paranid);
                        this->CheckSYSplit->Checked = xsp->isShipyard(ShipyardRace::Split);
                        this->CheckSYFriend->Checked = xsp->isShipyard(ShipyardRace::Friend);
                        this->CheckSYPirate->Checked = xsp->isShipyard(ShipyardRace::Pirates);
                        this->CheckSYXenon->Checked = xsp->isShipyard(ShipyardRace::Xenon);
                        this->CheckSYTerran->Checked = xsp->isShipyard(ShipyardRace::Terran);
                        this->CheckSYATF->Checked = xsp->isShipyard(ShipyardRace::ATF);
                        this->CheckSYYaki->Checked = xsp->isShipyard(ShipyardRace::Yaki);

                        this->UpdateShipText();
                        this->UpdateShipPartList();
                }
                else if ( m_pPackage->GetType() == TYPE_SPK )
                {
                        CSpkFile *spk = (CSpkFile *)m_pPackage;
                        
                        this->ComboType->Text = "Custom";
                        this->ComboType->Enabled = false;

                        this->ComboPluginType->SelectedIndex = spk->pluginType();

                        if ( spk->IsLibrary() )
                                this->RadioTypeLibrary->Checked = true;
                        else if ( spk->IsCustomStart() )
                                this->RadioTypeStart->Checked = true;
                        else if ( spk->IsPackageUpdate() )
                                this->RadioTypeUpdate->Checked = true;
                        else if ( spk->IsPatch() )
                                this->RadioTypePatch->Checked = true;
                        else
                        {
                                this->RadioTypeScript->Checked = true;
                                this->ComboType->SelectedIndex = spk->GetScriptType();
                                this->ComboType->Enabled = true;
                                if ( this->ComboType->SelectedIndex == CSpkFile::SCRIPTTYPE_CUSTOM )
                                        this->TextCustomType->Text = _US(spk->customScriptType(m_pP->GetLanguage()));
                        }

                        this->CheckOther->Checked = spk->IsAnotherMod();
                        this->TextOtherAuthor->Enabled = this->CheckOther->Checked;
                        this->TextOtherName->Enabled = this->CheckOther->Checked;
                        this->ButFromFile->Enabled = this->CheckOther->Checked;

                        if ( spk->IsAnotherMod() )
                        {
                                this->TextOtherAuthor->Text = _US(spk->otherAuthor());
                                this->TextOtherName->Text = _US(spk->otherName());
                        }

                        this->UpdateWares();
                        this->UpdateScriptType();
                }

                if ( !m_pPackage->creationDate().empty() ) {
                        int day = m_pPackage->creationDate().token(L"/", 1);
                        int month = m_pPackage->creationDate().token(L"/", 2);
                        int year = m_pPackage->creationDate().token(L"/", 3);
                        if ( month > 12 && day <= 12 ) { int temp = day; day = month; month = temp; }
                        if ( month < 1 ) month = 1;
                        if ( month > 12 ) month = 12;
                        if ( day < 1 ) day = 1;
                        if ( day > 31 ) day = 1;
                        if ( year < 1900 ) year += 2000;
                        try {
                                this->CreationDate->Value = DateTime(year, month, day);
                        } catch(System::ArgumentOutOfRangeException ^) {
                                this->CreationDate->Value = DateTime::Today;
                        }
                }
                else
                        this->CreationDate->Value = DateTime::Today;

                this->CreationDate->Checked = true;

                this->TextForum->Text = _US(m_pPackage->forumLink());
                this->TextEmail->Text = _US(m_pPackage->email());
                this->TextWebsite->Text = _US(m_pPackage->webSite());
                this->TextWebAddress->Text = _US(m_pPackage->webAddress());

                this->UpdateGamesList();
                this->UpdateFileList();
                this->UpdateMirrors();
                this->UpdatePackageNames();

                m_bSortingAsc = true;
                m_iSortingCol = 1;
                this->ListFiles->ListViewItemSorter = gcnew ListViewItemComparer(m_iSortingCol, !m_bSortingAsc);

                this->UpdateDisplayPic();
                this->UpdateDisplayIcon();
                this->UpdateRatings();
                this->UpdateText();
                this->UpdateDependacies();
                this->UpdateGlobals();

                // delete the pages
                if ( m_pPackage->GetType() != TYPE_XSP )
                {
                        delete this->PageShip;
                        delete this->PageRaw;
                        delete this->PageShipComp;
                        this->PageShip = nullptr;
                        this->PageRaw = nullptr;
                        this->PageShipComp = nullptr;
                        this->PanelShip->Hide();
                        this->ToolCustomise->Visible = false;
                }
                else if ( m_pPackage->GetType() != TYPE_SPK )
                {
                        delete this->PagePackage;
                        delete this->PageWares;
                        this->PageWares = nullptr;
                        this->PagePackage = nullptr;
                }

                m_bLoading = false;
        }

        void PackageForm::UpdateDependacies()
        {
                this->ListDep->Items->Clear();
                for ( SNeededLibrary *nl = m_pPackage->GetNeededLibraries()->First(); nl; nl = m_pPackage->GetNeededLibraries()->Next() )
                {
                        ListViewItem ^item = gcnew ListViewItem(_US(nl->sName));
                        item->SubItems->Add(_US(nl->sAuthor));
                        item->SubItems->Add(_US(nl->sMinVersion));
                        item->ImageIndex = 3;
                        this->ListDep->Items->Add(item);
                }
                this->ListDep->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);
        }

        void PackageForm::UpdateGlobals()
        {
                this->listGlobals->Items->Clear();
                auto& list = m_pPackage->getGlobals();
                for (auto itr = list.begin(); itr != list.end(); itr++)
                {
                        ListViewItem^ item = gcnew ListViewItem(_US((*itr)->str));
                        item->SubItems->Add(_US((*itr)->data));
                        item->ImageIndex = 3;
                        this->listGlobals->Items->Add(item);
                }
        }

        void PackageForm::UpdateShipPartList()
        {
                if ( !m_pPackage )
                        return;
                CXspFile *xsp = (CXspFile *)m_pPackage;

                // first lets adjust out columns
                int numColums = 1;
                this->ListShipPart->Visible = true;
                this->ListShipPart->Items->Clear();
                switch ( this->ComboShipPart->SelectedIndex )
                {
                        case 0: // componants
                                numColums = 3;
                                this->ColumnPart1->Text = "Section";
                                this->ColumnPart2->Text = "ID";
                                this->ColumnPart3->Text = "Data";
                                for ( SComponent *c = xsp->GetComponents()->First(); c; c = xsp->GetComponents()->Next() )
                                {
                                        ListViewItem ^item = gcnew ListViewItem(_US(c->sSection));
                                        item->ImageKey = "components";
                                        item->SubItems->Add(_US(c->sSection2));
                                        item->SubItems->Add(_US(c->sData));
                                        this->ListShipPart->Items->Add(item);
                                }
                                break;
                        case 1: // dummies
                                numColums = 2;
                                this->ColumnPart1->Text = "Section";
                                this->ColumnPart2->Text = "Data";
                                for ( SDummy *d = xsp->GetDummies()->First(); d; d = xsp->GetDummies()->Next() )
                                {
                                        ListViewItem ^item = gcnew ListViewItem(_US(d->sSection));
                                        item->SubItems->Add(_US(d->sData));
                                        item->ImageKey = "dummies";
                                        this->ListShipPart->Items->Add(item);
                                }
                                break;
                        case 2: // Cockpit
                                numColums = 3;
                                this->ColumnPart1->Text = "ID";
                                this->ColumnPart2->Text = "Index";
                                this->ColumnPart3->Text = "Data";
                                for ( SCockpit *c = xsp->GetCockpits()->First(); c; c = xsp->GetCockpits()->Next() )
                                {
                                        Utils::WString cName = c->sCockpit;
                                        cName = cName.token(L";", -2);
                                        while ( cName.right(1) == L";" )
                                                cName.truncate(-1);
                                        ListViewItem ^item = gcnew ListViewItem(_US(cName));
                                        if ( c->iIndex == -1 )
                                                item->SubItems->Add("<PACKAGE>");
                                        else
                                                item->SubItems->Add(Convert::ToString(c->iIndex));
                                        item->SubItems->Add(_US(c->sCockpit));
                                        item->ImageKey = "cockpit";
                                        this->ListShipPart->Items->Add(item);
                                }
                                break;
                        case 3: // CutData
                                numColums = 1;
                                this->ColumnPart1->Text = "Cuts";
                                for(auto itr = xsp->getCutData().begin(); itr != xsp->getCutData().end(); itr++)
                                {
                                        ListViewItem ^item = gcnew ListViewItem(_US((*itr)->str));
                                        item->ImageKey = "cutdata";
                                        this->ListShipPart->Items->Add(item);
                                }
                                break;
                        case 4: // Bodies
                                numColums = 2;
                                this->ColumnPart1->Text = "Section";
                                this->ColumnPart2->Text = "Bodies";
                                for(auto itr = xsp->getBodies().begin(); itr != xsp->getBodies().end(); itr++)
                                {
                                        ListViewItem ^item = gcnew ListViewItem(_US((*itr)->str.token(L";", 1)));
                                        item->SubItems->Add(_US((*itr)->str.tokens(L";", 2)));
                                        item->ImageKey = "bodies";
                                        this->ListShipPart->Items->Add(item);
                                }
                                break;
                        case 5: // Animations
                                numColums = 1;
                                this->ColumnPart1->Text = "Animations";
                                for(auto itr = xsp->getAnimations().begin(); itr != xsp->getAnimations().end(); itr++)
                                {
                                        ListViewItem ^item = gcnew ListViewItem(_US((*itr)->str));
                                        item->ImageKey = "animations";
                                        this->ListShipPart->Items->Add(item);
                                }
                                break;

                        // dont know what we are supposed to be displaying
                        default:
                                this->ListShipPart->Visible = false;
                }

                this->ListShipPart->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);
                // adjust size of columns
                if ( numColums < 3 )
                        this->ColumnPart3->Width = 0;
                if ( numColums < 2 )
                        this->ColumnPart2->Width = 0;
        }

        void PackageForm::UpdateShipText()
        {
                CXspFile *xsp = (CXspFile *)m_pPackage;

                this->ListShipText->Items->Clear();

                for ( SText *t = xsp->GetTexts()->First(); t; t = xsp->GetTexts()->Next() )
                {
                        ListViewItem ^item = gcnew ListViewItem(System::Convert::ToString(t->iId));
                        item->ImageIndex = 0;
                        item->SubItems->Add(_US(t->sName));
                        item->SubItems->Add(_US(t->sDesc));
                        this->ListShipText->Items->Add(item);
                }

                this->ListShipText->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);
        }

        void PackageForm::UpdateDisplayPic()
        {
                System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(PackageForm::typeid));
                this->ButPicBack->Enabled = false;
                this->ButPicNext->Enabled = false;
                if ( m_pDisplayFile )
                {
                        Utils::WString filePointer = m_pDisplayFile->filePointer();
                        filePointer = filePointer.findReplace(L"/", L"\\");
                        filePointer = filePointer.findReplace(L"\\\\", L"\\");
                        if ( System::IO::File::Exists(_US(filePointer)) )
                        {
                                Bitmap ^myBitmap = gcnew Bitmap(_US(filePointer));
                                if ( myBitmap )
                                        this->DisplayPicture->Image = dynamic_cast<Image ^>(myBitmap);
                        }
                        this->ButPicDel->Enabled = true;

                        if ( m_pPackage->GetFirstFile(FILETYPE_ADVERT) != m_pDisplayFile )
                                this->ButPicBack->Enabled = true;
                        if ( m_pPackage->GetNextFile(m_pDisplayFile)  )
                                this->ButPicNext->Enabled = true;
                }
                else
                {
                        this->ButPicDel->Enabled = false;
                        this->DisplayPicture->Image = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"DisplayPicture.Image")));
                }

        }

        void PackageForm::UpdateDisplayIcon()
        {
                System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(PackageForm::typeid));

                m_pTabPage->ImageIndex = 0;

                if ( m_pPackage->GetType() == TYPE_XSP )
                        this->DisplayIcon->Image = this->imageList1->Images[1];
                else
                {
                        this->DisplayIcon->Image = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"DisplayIcon.Image")));

                        int num = -1;
                        if ( m_pPackage->GetType() == TYPE_SPK )
                        {
                                CSpkFile *spk = (CSpkFile *)m_pPackage;
                                if ( spk->IsLibrary() )
                                        num = 3;
                                else if ( spk->IsPackageUpdate() )
                                        num = 6;
                                else if ( spk->IsPatch() )
                                        num = 7;
                                else if ( spk->IsCustomStart() )
                                        num = 8;
                        }

                        if ( num == -1 && m_pPackage->IsFakePatch() )
                                num = 2;

                        if ( num != -1 )
                        {
                                this->DisplayIcon->Image = this->imageList1->Images[num];
                                m_pTabPage->ImageIndex = num;
                        }
                }

                this->ButIconDel->Enabled = false;

                if ( m_pPackage->icon() )
                {
                        this->ButIconDel->Enabled = true;
                        Utils::WString filePointer = m_pPackage->icon()->filePointer();
                        filePointer = filePointer.findReplace(L"/", L"\\");
                        filePointer = filePointer.findReplace(L"\\\\", L"\\");
                        String ^file = _US(filePointer);
                        if ( System::IO::File::Exists(file) )
                        {
                                Bitmap ^myBitmap = gcnew Bitmap(file);
                                if ( myBitmap )
                                {
                                        this->DisplayIcon->Image = dynamic_cast<Image ^>(myBitmap);
                                        this->imageList1->Images->Add(file, myBitmap);
                                        m_pTabPage->ImageIndex = this->imageList1->Images->IndexOfKey(file);
                                        if ( m_pTabPage->ImageIndex == -1 )
                                                m_pTabPage->ImageIndex = 0;
                                }
                        }
                }

                if ( m_pTabPage->ImageIndex == 0 )
                {
                        if ( m_pPackage->GetType() == TYPE_XSP )
                                m_pTabPage->ImageIndex = 1;
                }

                m_pMenuItem->Image = this->imageList1->Images[m_pTabPage->ImageIndex];
        }

        void PackageForm::UpdateGameVersion()
        {
                bool restoreLoad = m_bLoading;
                m_bLoading = true;

                ComboVersion->BeginUpdate();
                ComboVersion->Items->Clear();

                this->TextExactVersion->Hide();

                SGameExe *exe = NULL;
                if ( ButGame->ImageIndex >= 0 )
                        exe = m_pP->GetGameExe()->game((m_pPackage) ? ButGame->ImageIndex : -1);
                if ( exe )
                {                       
                        ComboVersion->Items->Add("Original");
                        for ( int i = 0; i < exe->lVersions.size(); i++ )
                        {
                                SGameExeVersion *v = exe->lVersions[i];
                                ComboVersion->Items->Add(_US(v->sName));
                        }
                        ComboVersion->Items->Add("Exact (Custom)");
                        ComboVersion->Enabled = true;
                }
                else
                {
                        ComboVersion->Enabled = false;
                }
                

                ComboVersion->EndUpdate();

                if ( !restoreLoad )
                        m_bLoading = false;
        }

        void PackageForm::UpdateRatings()
        {
                this->PicEase1->BackColor = System::Drawing::Color::Transparent;
                this->PicEase2->BackColor = System::Drawing::Color::Transparent;
                this->PicEase3->BackColor = System::Drawing::Color::Transparent;
                this->PicEase4->BackColor = System::Drawing::Color::Transparent;
                this->PicEase5->BackColor = System::Drawing::Color::Transparent;

                this->PicChange1->BackColor = System::Drawing::Color::Transparent;
                this->PicChange2->BackColor = System::Drawing::Color::Transparent;
                this->PicChange3->BackColor = System::Drawing::Color::Transparent;
                this->PicChange4->BackColor = System::Drawing::Color::Transparent;
                this->PicChange5->BackColor = System::Drawing::Color::Transparent;

                this->PicRec1->BackColor = System::Drawing::Color::Transparent;
                this->PicRec2->BackColor = System::Drawing::Color::Transparent;
                this->PicRec3->BackColor = System::Drawing::Color::Transparent;
                this->PicRec4->BackColor = System::Drawing::Color::Transparent;
                this->PicRec5->BackColor = System::Drawing::Color::Transparent;

                if ( m_pPackage->easeOfUse() >= 1 )
                        this->PicEase1->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->easeOfUse() >= 2 )
                        this->PicEase2->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->easeOfUse() >= 3 )
                        this->PicEase3->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->easeOfUse() >= 4 )
                        this->PicEase4->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->easeOfUse() >= 5 )
                        this->PicEase5->BackColor = System::Drawing::Color::Red;

                if ( m_pPackage->recommended() >= 1 )
                        this->PicRec1->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->recommended() >= 2 )
                        this->PicRec2->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->recommended() >= 3 )
                        this->PicRec3->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->recommended() >= 4 )
                        this->PicRec4->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->recommended() >= 5 )
                        this->PicRec5->BackColor = System::Drawing::Color::Red;

                if ( m_pPackage->gameChanging() >= 1 )
                        this->PicChange1->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->gameChanging() >= 2 )
                        this->PicChange2->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->gameChanging() >= 3 )
                        this->PicChange3->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->gameChanging() >= 4 )
                        this->PicChange4->BackColor = System::Drawing::Color::Red;
                if ( m_pPackage->gameChanging() >= 5 )
                        this->PicChange5->BackColor = System::Drawing::Color::Red;

                if ( m_pPackage->easeOfUse() < 0 )
                        this->GroupEase->Text = "Ease of Use";
                else
                        this->GroupEase->Text = "Ease of Use (" + System::Convert::ToString(m_pPackage->easeOfUse()) + ")";

                if ( m_pPackage->gameChanging() < 0 )
                        this->GroupChange->Text = "Game Changing";
                else
                        this->GroupChange->Text = "Game Changing (" + System::Convert::ToString(m_pPackage->gameChanging()) + ")";

                if ( m_pPackage->recommended() < 0 )
                        this->GroupRec->Text = "Recommended";
                else
                        this->GroupRec->Text = "Recommended (" + System::Convert::ToString(m_pPackage->recommended()) + ")";
        }

        void PackageForm::Setup()
        {
                m_bLoading = true;

                this->ComboFileType->Items->Add("All Files");
                for ( int i = 0; i < FILETYPE_MAX; i++ )
                        this->ComboFileType->Items->Add(_US(GetFileTypeString(i)));
                this->ComboFileType->SelectedIndex = 0;

                this->PanelShip->Hide();

                m_bSortingAsc = true;
                m_iSortingCol = 1;

                this->ListFiles->ColumnClick += gcnew ColumnClickEventHandler(this, &Creator::PackageForm::SortList);
                this->ListFiles->ItemChecked += gcnew ItemCheckedEventHandler(this, &PackageForm::Event_FileChecked);

                this->ContextGames->Items->Clear();

                this->ComboGameFilter->Items->Clear();
                this->ToolGame->DropDownItems->Clear();

                this->ComboGameFilter->Items->Add("- None -");
                this->ComboGameFilter->Items->Add("- All Games -");

                ToolStripItem ^newItem = this->ToolGame->DropDownItems->Add("- All Games -");
                newItem->Tag = Convert::ToString(0);
                newItem->Click += gcnew System::EventHandler(this, &PackageForm::SetGame_Selected);

                newItem = this->ToolGame->DropDownItems->Add("------");
                newItem->Enabled = false;

                if (!_addGameItem)
                {
                        _addGameItem = gcnew System::Windows::Forms::ToolStripMenuItem;
                        _addGameItem->Text = "Add Game";
                }
                this->ToolGame->DropDownItems->Add(_addGameItem);

                if (!_removeGameItem)
                {
                        _removeGameItem = gcnew System::Windows::Forms::ToolStripMenuItem;
                        _removeGameItem->Text = "Remove Game";
                }
                this->ToolGame->DropDownItems->Add(_removeGameItem);

                newItem = this->ToolGame->DropDownItems->Add("------");
                newItem->Enabled = false;

                for ( int i = 0; i < m_pP->GetGameExe()->numGames(); i++ )
                {
                        SGameExe *gameExe = m_pP->GetGameExe()->game(i);
                        if ( gameExe )
                        {
                                System::Windows::Forms::ToolStripMenuItem ^newItem = gcnew System::Windows::Forms::ToolStripMenuItem;
                                newItem->Text = _US(gameExe->sName);
                                newItem->Tag = Convert::ToString(i + 1);
                                if (i < this->imageListGames->Images->Count)
                                        newItem->Image = this->imageListGames->Images[i];
                                newItem->Click += gcnew System::EventHandler(this, &PackageForm::ContextGame_Selected);
                                this->ContextGames->Items->Add(newItem);

                                System::Windows::Forms::ToolStripMenuItem ^newItem2 = gcnew System::Windows::Forms::ToolStripMenuItem;
                                newItem2->Text = _US(gameExe->sName);
                                newItem2->Tag = Convert::ToString(i + 1);
                                if (i < this->imageListGames->Images->Count)
                                        newItem2->Image = this->imageListGames->Images[i];
                                newItem2->Click += gcnew System::EventHandler(this, &PackageForm::SetGame_Selected);
                                this->ToolGame->DropDownItems->Add(newItem2);
                                this->ComboGameFilter->Items->Add(_US(gameExe->sName));

                                newItem2 = gcnew System::Windows::Forms::ToolStripMenuItem;
                                newItem2->Text = _US(gameExe->sName);
                                newItem2->Tag = Convert::ToString(i + 1);
                                if (i < this->imageListGames->Images->Count)
                                        newItem2->Image = this->imageListGames->Images[i];
                                newItem2->Click += gcnew System::EventHandler(this, &PackageForm::AddGame_Selected);
                                _addGameItem->DropDownItems->Add(newItem2);

                                newItem2 = gcnew System::Windows::Forms::ToolStripMenuItem;
                                newItem2->Text = _US(gameExe->sName);
                                newItem2->Tag = Convert::ToString(i + 1);
                                if (i < this->imageListGames->Images->Count)
                                        newItem2->Image = this->imageListGames->Images[i];
                                newItem2->Click += gcnew System::EventHandler(this, &PackageForm::RemoveGame_Selected);
                                _removeGameItem->DropDownItems->Add(newItem2);
                        }
                }

                this->ComboGameFilter->SelectedIndex = 0;

                this->ButGame->Text = "- Select Game -";
                this->ButGameAdd->Enabled = false;

                m_pTypeList->clear();
                for ( int i = 0; i < CSpkFile::SCRIPTTYPE_MAX; i++ )
                {
                        m_pTypeList->pushBack(CSpkFile::GetScriptTypeStringStatic(i, m_pP->GetLanguage()));
                        ComboType->Items->Add(_US(CSpkFile::GetScriptTypeStringStatic(i, m_pP->GetLanguage())));
                }

                this->CreationDate->Value = DateTime::Today;

                m_bLoading = false;
        }

        void PackageForm::UpdateGamesList()
        {
                this->ListGames->Items->Clear();
                for ( SGameCompat *game = m_pPackage->GetGameCompatabilityList()->First(); game; game = m_pPackage->GetGameCompatabilityList()->Next() ) {
                        ListViewItem ^item = gcnew ListViewItem(_US(m_pP->getGameNameFromType(game->iGame)));
                        item->ImageIndex = (game->iGame < 0) ? -1 : (game->iGame - 1);
                        if ( !game->sVersion.empty() ) {
                                item->SubItems->Add("Exact: " + _US(game->sVersion));
                        }
                        else {
                                item->SubItems->Add(_US(m_pP->getGameVersionFromType(game->iGame, game->iVersion, game->sVersion)));
                        }
                        item->Tag = game->iGame;
                        this->ListGames->Items->Add(item);
                }

                this->ListGames->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);
        }

        void PackageForm::UpdateFileList()
        {
                this->ButRemoveFile->Enabled = false;

                int pos = 0;
                this->ListFiles->Items->Clear();
                if ( m_pPackage ) {
                        for ( C_File *file = m_pPackage->GetFileList()->First(); file; file = m_pPackage->GetFileList()->Next() )
                        {
                                file->SetPos(pos++);
                                if (this->ComboGameFilter->SelectedIndex == 1)
                                {
                                        if (file->game() > 0 && file->game() != 1 << 31)
                                                continue;
                                }
                                else if (this->ComboGameFilter->SelectedIndex > 0)
                                {
                                        if (!(1 << (this->ComboGameFilter->SelectedIndex - 1) & file->game()))
                                                continue;
                                }
                                if ( this->ComboFileType->SelectedIndex == 0 || (this->ComboFileType->SelectedIndex - 1) == file->GetFileType() )
                                        this->AddFile(file);
                        }
                        ((Form1 ^)this->MdiParent)->UpdateStatus();
                }

                this->ListFiles->AutoResizeColumns(ColumnHeaderAutoResizeStyle::HeaderSize);
        }

        void PackageForm::AddFile(C_File *file)
        {
                ListViewItem ^item = gcnew ListViewItem("");

                if ( file->GetData() )
                {
                        item->SubItems->Add(_US("<PACKAGE>/" + file->getNameDirectory(NULL)));
                        item->SubItems->Add(_US(file->uncompressedSizeString()));
                }
                else
                {
                        item->SubItems->Add(_US(file->fullFilename()));
                        item->SubItems->Add(_US(SPK::GetSizeString(file->GetSize())));
                }

                if ( file->IsFakePatch() )
                        item->SubItems->Add("Mod (Fakepatch)");
                else
                        item->SubItems->Add(_US(file->fileTypeString()));

                if ( !file->dir().empty() )
                        item->SubItems->Add(_US(file->dir()));
                else
                        item->SubItems->Add("");

                if ( file->IsSigned() )
                        item->SubItems->Add("Yes");
                else
                        item->SubItems->Add("No");

                if ( !file->game() || file->game() == (1 << 31))
                        item->SubItems->Add("All Games");
                else
                {
                        if (file->game() & (1 << 31))
                        {                       
                                Utils::WString sGames = L"";
                                for (int i = 0; i < 31; ++i)
                                {
                                        int gameMask = 1 << i;
                                        if (file->game() & gameMask)
                                        {
                                                Utils::WString sGame;
                                                SGameExe *exe = _pPackages->GetGameExe()->game(i - 1);
                                                if (exe)
                                                        sGame = exe->sName;
                                                else
                                                        sGame = L"Game: " + Utils::WString::Number(i);

                                                if (sGames.empty())
                                                        sGames = sGame;
                                                else
                                                        sGames = sGames + L", " + sGame;
                                        }
                                }
                                item->SubItems->Add(_US(sGames));
                        }
                        else
                        {
                                SGameExe *exe = _pPackages->GetGameExe()->game(file->game() - 1);
                                if (exe) {
                                        item->SubItems->Add(_US(exe->sName));
                                }
                                else {
                                        item->SubItems->Add("Game: " + file->game());
                                }
                        }
                }

                item->Tag = _US(Utils::WString::Number(file->GetPos()));
                if ( file->IsFakePatch() )
                        item->ImageKey = "fakepatch";
                else
                        item->ImageIndex = file->GetFileType();

                item->Checked = file->IsShared();

                this->ListFiles->Items->Add(item);
        }

        void PackageForm::AddNewFile()
        {
                // add filters
                OpenFileDialog ^ofd = gcnew OpenFileDialog();

                System::String ^filter;
                for ( int i = 0; i < FILETYPE_MAX; i++ )
                {
                        if ( filter )
                                filter += "|";
                        filter += _US(GetFileTypeString(i));
                        filter += "|";
                        // add extensions
                        switch ( i )
                        {
                                case FILETYPE_SCRIPT:
                                case FILETYPE_UNINSTALL:
                                case FILETYPE_MAP:
                                case FILETYPE_TEXT:
                                case FILETYPE_MISSION:
                                        filter += "*.pck;*.xml";
                                        break;

                                case FILETYPE_README:
                                        filter += "*.txt;*.doc;*.docx;*.pdf";
                                        break;

                                case FILETYPE_MOD:
                                        filter += "*.cat";
                                        break;

                                case FILETYPE_SOUND:
                                        filter += "*.wav";
                                        break;

                                case FILETYPE_SCREEN:
                                case FILETYPE_ADVERT:
                                        filter += "*.jpg;*.png";
                                        break;

                                case FILETYPE_SHIPSCENE:
                                case FILETYPE_COCKPITSCENE:
                                        filter += "*.pbd;*.bod";
                                        break;

                                case FILETYPE_SHIPMODEL:
                                        filter += "*.pbd;*.bod;*.bob;*.pbb";
                                        break;

                                default:
                                        filter += "*.*";
                        }
                }
                ofd->Filter = filter;
                ofd->FilterIndex = 1;
                ofd->RestoreDirectory = true;
                ofd->Multiselect = true;
                ofd->Title = "Select File(s) to add to package";
                if ( ofd->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                {
                        Utils::WString dir;
                        if ( C_File::DoesTypeHaveExtraDir(ofd->FilterIndex - 1) )
                        {
                                InputBox ^input = gcnew InputBox("Enter the directory to add files to", ((ofd->FilterIndex - 1) == FILETYPE_EXTRA) ? "PluginManager/Extras/$scriptname" : "");
                                if ( input->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                                        dir = _WS(input->GetInput());
                        }
                        array<System::String ^> ^fileArray = ofd->FileNames;
                        for ( int i = 0; i < fileArray->Length; i++ )
                        {
                                System::String ^file = fileArray[i];
                                FileType filetype = m_pP->adjustFileType(_WS(file), static_cast<FileType>(ofd->FilterIndex - 1));
                                C_File *f = m_pPackage->addFile(_WS(file), dir, filetype, this->ComboGameFilter->SelectedIndex > 1 ? (1 << (this->ComboGameFilter->SelectedIndex - 1) | 1 << 31) : 0);
                                if ( (ofd->FilterIndex - 1) == FILETYPE_MOD )
                                        m_pPackage->addFile(CFileIO(_WS(file)).changeFileExtension(L"dat"), dir, filetype);
                        }
                        m_pPackage->updateSigned(false);
                        this->UpdateFileList();
                        this->UpdateDisplayPic();
                        this->UpdateChanged();
                }
        }

        bool PackageForm::CheckSave()
        {
                if ( m_pPackage->name().empty() )
                {
                        MessageBox::Show(this, "You must specify a package name", "Invalid Entry", MessageBoxButtons::OK, MessageBoxIcon::Stop);
                        return false;
                }
                if ( m_pPackage->author().empty() )
                {
                        MessageBox::Show(this, "You must specify an Author", "Invalid Entry", MessageBoxButtons::OK, MessageBoxIcon::Stop);
                        return false;
                }
                if ( m_pPackage->version().empty() )
                {
                        MessageBox::Show(this, "You must specify a version number", "Invalid Entry", MessageBoxButtons::OK, MessageBoxIcon::Stop);
                        return false;
                }

                if ( m_pPackage->GetType() == TYPE_SPK )
                {
                        if ( ((CSpkFile *)m_pPackage)->IsPackageUpdate() )
                        {
                                SNeededLibrary *n = m_pPackage->findPackageNeeded(L"<package>", L"<author>");
                                if ( !n )
                                        m_pPackage->addNeededLibrary(L"<package>", L"<author>", L"1.00");
                                n = m_pPackage->findPackageNeeded(L"<package>", L"<author>");

                                if ( n )
                                {
                                        if ( ((CSpkFile *)m_pPackage)->version().compareVersion(n->sMinVersion) != COMPARE_OLDER )
                                        {
                                                MessageBox::Show(this, "The depencay vesion (" + _US(n->sMinVersion) + ") is too high, it must be lower than the current version (" + _US(m_pPackage->version()) + ")", "Invalid Entry", MessageBoxButtons::OK, MessageBoxIcon::Stop);
                                                return false;
                                        }
                                }
                        }
                        else if ( ((CSpkFile *)m_pPackage)->IsCustomStart() )
                        {
                                if ( !((CSpkFile *)m_pPackage)->CheckValidCustomStart() )
                                {
                                        MessageBox::Show(this, "For a custom start, you must include an initplayer script", "Invalid Entry", MessageBoxButtons::OK, MessageBoxIcon::Stop);
                                        return false;
                                }
                        }
                        else if ( ((CSpkFile *)m_pPackage)->IsPatch() )
                        {
                                if ( ((CSpkFile *)m_pPackage)->otherAuthor().empty() || ((CSpkFile *)m_pPackage)->otherName().empty() )
                                {
                                        MessageBox::Show(this, "For a mod patch, you must specify the parent mod that this will be patching\nEnter the parent mod name and author", "Invalid Entry", MessageBoxButtons::OK, MessageBoxIcon::Stop);
                                        return false;
                                }
                        }
                }

                 System::DateTime ^time = DateTime(this->CreationDate->Value);
                 m_pPackage->setCreationDate(_WS(System::Convert::ToString(time->Day) + "/" + System::Convert::ToString(time->Month) + "/" + System::Convert::ToString(time->Year)));

                return true;
        }

        void PackageForm::Save()
        {
                if ( !this->CheckSave() )
                        return;

                if ( m_pPackage->filename().empty() )
                {
                        this->SaveAs();
                        return;
                }

                if ( m_pPackage->GetType() == TYPE_XSP )
                        ((CXspFile *)m_pPackage)->AdjustCockpits();

                SaveDialog ^save = gcnew SaveDialog(m_pPackage, _US(m_pPackage->filename()));
                if ( save->ShowDialog(this) == Windows::Forms::DialogResult::Cancel )
                        return;

                this->UpdateFileList();
                m_pPackage->adjustChanged(false);
                this->UpdateChanged();

                if ( m_pSettings->bGenerateUpdate )
                        m_pPackage->createUpdateFile(CFileIO(m_pPackage->filename()).dir());

                MessageBox::Show("Package: " + _US(m_pPackage->filename()) + "\nHas been saved!", "Saved", MessageBoxButtons::OK, MessageBoxIcon::Information);
        }

        void PackageForm::SaveAs()
        {
                if ( !this->CheckSave() )
                        return;

                SaveFileDialog ^ofd = gcnew SaveFileDialog();
                if ( m_pPackage->GetType() == TYPE_XSP )
                        ofd->Filter = "Ship Files (*.xsp)|*.xsp";
                else
                        ofd->Filter = "Package Files (*.spk)|*.spk";
                ofd->AddExtension = true;
                Utils::WString filename = m_pPackage->filename();
                if (filename.empty())
                        filename = m_pPackage->getAutosaveName();
                filename = filename.findReplace(L"/", L"\\");
                ofd->FileName = _US(filename);
                ofd->FilterIndex = 1;
                ofd->RestoreDirectory = true;
                if ( ofd->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                {
                        m_pPackage->setFilename(_WS(ofd->FileName));
                        m_sFilename = ofd->FileName;
                        m_pTabPage->Text = _US(CFileIO(m_pPackage->filename()).filename());
                        m_pMenuItem->Text = m_pTabPage->Text;
                        this->Save();
                }
        }

        System::Void PackageForm::PackageForm_Closing(System::Object^  sender, CancelEventArgs^  e)     {
                if ( m_pPackage->hasChanged() )
                {
                        String ^name = m_pTabPage->Text;
                        if ( name[name->Length - 1] == '*' )
                                name = name->Remove(name->Length - 1);
                        System::Windows::Forms::DialogResult result = MessageBox::Show("Would you like to save changes to the package?\n\n" + name, "Save Package", MessageBoxButtons::YesNoCancel, MessageBoxIcon::Question);

                        if ( result == System::Windows::Forms::DialogResult::Cancel )
                        {
                                e->Cancel = true;
                                return;
                        }
                        else if ( result == System::Windows::Forms::DialogResult::Yes )
                        {
                                if ( !this->CheckSave() )
                                {
                                        e->Cancel = true;
                                        return;
                                }

                                if ( m_pPackage->filename().empty() )
                                {
                                        SaveFileDialog ^ofd = gcnew SaveFileDialog();
                                        if ( m_pPackage->GetType() == TYPE_XSP )
                                                ofd->Filter = "Ship Files (*.xsp)|*.xsp";
                                        else
                                                ofd->Filter = "Package Files (*.spk)|*.spk";
                                        ofd->FilterIndex = 1;
                                        ofd->RestoreDirectory = true;
                                        if ( ofd->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                                                m_pPackage->setFilename(_WS(ofd->FileName));
                                        else
                                        {
                                                 e->Cancel = true;
                                                 return;
                                        }
                                }

                                if ( !m_pPackage->writeFile(m_pPackage->filename()) )
                                {
                                        e->Cancel = true;
                                        MessageBox::Show("Unable to save package\n" + _US(m_pPackage->filename()), "Save Error", MessageBoxButtons::OK, MessageBoxIcon::Error);
                                        return;
                                }
                        }
                }

                delete m_pPackage;
                m_pPackage = NULL;
        }

        void PackageForm::UpdateMirrors()
        {
                this->ListMirrors->Items->Clear();
                for (size_t i = 0; i < m_pPackage->getMaxWebMirrors(); i++ )
                {
                        ListViewItem ^item = gcnew ListViewItem(_US(m_pPackage->getWebMirror(i)));
                        this->ListMirrors->Items->Add(item);
                        item->ImageIndex = 1;
                }

                this->ListMirrors->AutoResizeColumns(ColumnHeaderAutoResizeStyle::ColumnContent);
                if ( this->ListMirrors->Columns[0]->Width < 100 )
                        this->ListMirrors->Columns[0]->Width = 100;
        }

        void PackageForm::UpdatePackageNames()
        {
                this->ListNames->Items->Clear();
                for(auto itr = m_pPackage->namesList()->begin(); itr != m_pPackage->namesList()->end(); itr++)
                {
                        ListViewItem ^item = gcnew ListViewItem(Convert::ToString((*itr)->iLanguage));
                        item->SubItems->Add(_US((*itr)->sName));
                        item->ImageIndex = 0;
                        this->ListNames->Items->Add(item);
                }
                this->ListNames->AutoResizeColumns(ColumnHeaderAutoResizeStyle::ColumnContent);
                if ( this->ListNames->Columns[0]->Width < 100 )
                        this->ListNames->Columns[0]->Width = 100;
                if ( this->ListNames->Columns[1]->Width < 100 )
                        this->ListNames->Columns[1]->Width = 100;
        }

        void PackageForm::AddDisplayPic()
        {
                OpenFileDialog ^ofd = gcnew OpenFileDialog();
                ofd->Filter = "Display Images|*.gif;*.png;*.jpg";
                ofd->FilterIndex = 1;
                ofd->RestoreDirectory = true;
                ofd->Multiselect = true;
                ofd->Title = "Select the Display image to add";

                if ( ofd->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                {
                        array<System::String ^> ^fileArray = ofd->FileNames;
                        for ( int i = 0; i < fileArray->Length; i++ )
                                m_pDisplayFile = m_pPackage->addFile(_WS(fileArray[i]), L"", FILETYPE_ADVERT);

                        this->UpdateDisplayPic();
                        this->UpdateFileList();
                }
        }

        void PackageForm::AddDisplayIcon()
        {
                OpenFileDialog ^ofd = gcnew OpenFileDialog();
                ofd->Filter = "Icon Files|*.ico;*.png;*.bmp";
                ofd->FilterIndex = 1;
                ofd->RestoreDirectory = true;
                ofd->Multiselect = false;
                ofd->Title = "Select the Icon file to add";

                if ( ofd->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                {
                        Utils::WString file = _WS(ofd->FileName);
                        C_File *icon = new C_File(file);
                        if ( icon->ReadFromFile() )
                                m_pPackage->setIcon(icon, CFileIO(file).extension());

                        this->UpdateDisplayIcon();
                        this->UpdateChanged();
                }
        }

        void PackageForm::SaveText()
        {
                if ( this->TextText->Text->Length )
                {
                        if ( this->ListLang->SelectedIndex >= 0 )
                        {
                                int lang = _WS(this->ListLang->Text).toInt();
                                if ( this->RadioInstallAfter->Checked )                 m_pPackage->addInstallText(lang, false, _WS(this->TextText->Text));
                                else if ( this->RadioInstallBefore->Checked )   m_pPackage->addInstallText(lang, true, _WS(this->TextText->Text));
                                else if ( this->RadioUninstallBefore->Checked ) m_pPackage->addUninstallText(lang, true, _WS(this->TextText->Text));
                                else if ( this->RadioUninstallAfter->Checked )  m_pPackage->addUninstallText(lang, false, _WS(this->TextText->Text));
                                this->UpdateChanged();
                        }
                }
        }

        void PackageForm::LoadShipData()
        {
                OpenFileDialog ^ofd = gcnew OpenFileDialog();
                ofd->Filter = "All (*.cat, tships)|*.cat;tships.txt;tships.pck|TShips Files (tships.txt/pck)|tships.txt;tships.pck|Mod Files (*.cat)|*.cat";
                ofd->FilterIndex = 1;
                ofd->RestoreDirectory = true;
                ofd->Multiselect = false;
                ofd->Title = "Select the TShips/Mod file to load ship data from";

                if ( ofd->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                {
                        // if its a cat file, lets load the text
                        Hashtable ^catText = gcnew Hashtable();

                        if ( String::Compare(IO::FileInfo(ofd->FileName).Extension, ".cat") == 0 )
                        {
                                Utils::WStringList readText;
                                if ( m_pP->readTextPage(_WS(ofd->FileName), readText, false, 17) )
                                {
                                        for(auto itr = readText.begin(); itr != readText.end(); itr++)
                                        {
                                                String ^key = _US((*itr)->str);
                                                if ( catText->ContainsKey(key) )
                                                        catText[key] = _US((*itr)->data);
                                                else
                                                        catText->Add(key, _US((*itr)->data));
                                        }
                                }
                        }

                        Utils::WStringList list;
                        if (m_pP->loadShipData(_WS(ofd->FileName), list))
                        {
                                LoadShip ^ls = gcnew LoadShip();
                                for(auto itr = list.begin(); itr != list.end(); itr++)
                                {
                                        int tId = (*itr)->data.token(L";", 7).toInt();
                                        String ^name;
                                        if ( catText->ContainsKey(Convert::ToString(tId)) )
                                                name = Convert::ToString(catText[Convert::ToString(tId)]);
                                        else
                                                name = ((Form1 ^)this->MdiParent)->FindText(-1, 17, tId);
                                        String ^text = ((Form1 ^)this->MdiParent)->FindText(-1, 1266, (*itr)->data.token(L";", 46).toInt()) + " " + name;
                                        int variation = (*itr)->data.token(L";", 51).toInt();
                                        if ( variation )
                                                text = text + " " + ((Form1 ^)this->MdiParent)->FindText(-1, 17, 10000 + variation);
                                        ls->AddShip(_US((*itr)->str), text);
                                }

                                if ( ls->ShowDialog(this) == System::Windows::Forms::DialogResult::OK )
                                {
                                        Utils::WString data = list.findString(_WS(ls->GetData()));
                                        if (data.empty())
                                        {
                                                ((CXspFile *)m_pPackage)->setShipData(data);
                                                if ( ((CXspFile *)m_pPackage)->shipID().empty() )
                                                {
                                                        Utils::WString id = data.tokens(L";", -2);
                                                        while ( id.right(1) == L";" )
                                                                id.truncate((int)id.length() - 1);
                                                        ((CXspFile *)m_pPackage)->setShipID(id);
                                                        this->TextShipID->Text = _US(id);
                                                }

                                                ((CXspFile *)m_pPackage)->setShipData(data);
                                                this->TextShipData->Text = _US(data);
                                                this->NumTextID->Value = data.token(L";", 7).toInt();
                                                this->UpdateChanged();
                                        }
                                }
                        }
                        else
                                MessageBox::Show(this, "Unable to find any ship entries, invalid/missing TShips?", "Error Loading", MessageBoxButtons::OK, MessageBoxIcon::Error);
                }
        }

        void PackageForm::EditShipParts(bool edit)
        {
                 CXspFile *xsp = (CXspFile *)m_pPackage;
                 switch ( this->ComboShipPart->SelectedIndex )
                 {
                        case 0:
                                {
                                        AddShipPart ^component = gcnew AddShipPart((Form1 ^)this->MdiParent);
                                        component->SetComponent(edit);

                                        if ( edit )
                                        {
                                                component->SetSection(m_pSelectedItem->Text);
                                                component->SetSection2(m_pSelectedItem->SubItems[1]->Text);
                                                component->SetData(m_pSelectedItem->SubItems[2]->Text);
                                        }

                                        if ( component->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                                        {
                                                if ( edit )
                                                        xsp->removeComponent(_WS(m_pSelectedItem->Text), _WS(m_pSelectedItem->SubItems[1]->Text), _WS(m_pSelectedItem->SubItems[2]->Text));
                                                xsp->addComponent(_WS(component->GetSection()), _WS(component->GetSection2()), _WS(component->GetData()));
                                                if ( !edit )
                                                        this->UpdateShipPartList();
                                                else
                                                {
                                                        m_pSelectedItem->Text = component->GetSection();
                                                        m_pSelectedItem->SubItems[1]->Text = component->GetSection2();
                                                        m_pSelectedItem->SubItems[2]->Text = component->GetData();
                                                }
                                        }
                                }
                                break;
                        case 1:
                                {
                                        AddShipPart ^dummy = gcnew AddShipPart((Form1 ^)this->MdiParent);
                                        dummy->SetDummy(edit);

                                        if ( edit )
                                        {
                                                dummy->SetSection(m_pSelectedItem->Text);
                                                dummy->SetData(m_pSelectedItem->SubItems[1]->Text);
                                        }

                                        if ( dummy->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                                        {
                                                if ( edit )
                                                        xsp->removeDummy(_WS(m_pSelectedItem->Text), _WS(m_pSelectedItem->SubItems[1]->Text));
                                                xsp->addDummy(_WS(dummy->GetSection()), _WS(dummy->GetData()));
                                                if ( !edit )
                                                        this->UpdateShipPartList();
                                                else
                                                {
                                                        m_pSelectedItem->Text = dummy->GetSection();
                                                        m_pSelectedItem->SubItems[1]->Text = dummy->GetData();
                                                }
                                        }
                                }
                                break;

                        case 2:
                                {
                                        AddCockpit ^cockpit = gcnew AddCockpit();
                                        if ( edit )
                                                cockpit->SetEdit(m_pSelectedItem->Text, _US(_WS(m_pSelectedItem->SubItems[2]->Text).token(L";", 8)), _WS(m_pSelectedItem->SubItems[2]->Text).token(L";", 9).toInt());
                                        if ( cockpit->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                                        {
                                                if ( !edit )
                                                {
                                                        xsp->newCockpit(_WS(cockpit->GetID()), _WS(cockpit->GetScene()), cockpit->GetMask());
                                                        this->UpdateShipPartList();
                                                }
                                                else
                                                {
                                                        xsp->editCockpit(_WS(cockpit->GetID()), _WS(cockpit->GetScene()), cockpit->GetMask());
                                                        m_pSelectedItem->SubItems[2]->Text = _US(xsp->getCockpitData(_WS(cockpit->GetID())));
                                                }
                                        }
                                }
                                break;

                        case 3:
                                {
                                        if ( edit )
                                        {
                                                InputBox ^input2 = gcnew InputBox("Enter the filename for cut id: " + _US(_WS(m_pSelectedItem->Text).token(L";", 1)), _US(_WS(m_pSelectedItem->Text).token(L";", 2)));
                                                if ( input2->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                                                {
                                                        xsp->removeCutData(_WS(m_pSelectedItem->Text));
                                                        xsp->addCutData(_WS(m_pSelectedItem->Text).token(L";", 1) + L"; " + _WS(input2->GetInput()));
                                                        this->UpdateShipPartList();
                                                }
                                        }
                                        else
                                        {
                                                InputBox ^input = gcnew InputBox("Enter the cut id to add");
                                                if ( input->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                                                {
                                                        InputBox ^input2 = gcnew InputBox("Enter the filename for cut id: " + input->GetInput());
                                                        if ( input2->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                                                        {
                                                                xsp->addCutData(_WS(input->GetInput() + L"; " + input2->GetInput()));
                                                                this->UpdateShipPartList();
                                                        }
                                                }
                                        }
                                }
                                break;

                        case 4:
                                {
                                        AddShipPart ^dummy = gcnew AddShipPart((Form1 ^)this->MdiParent);
                                        dummy->SetBodies(edit);

                                        if ( edit )
                                        {
                                                dummy->SetSection(m_pSelectedItem->Text);
                                                dummy->SetData(m_pSelectedItem->SubItems[1]->Text);
                                        }

                                        if ( dummy->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                                        {
                                                if ( edit )
                                                        xsp->removeBodies(_WS(m_pSelectedItem->Text + ";" + m_pSelectedItem->SubItems[1]->Text));
                                                xsp->addBodies(_WS(dummy->GetSection() + ";" + dummy->GetData()));
                                                if ( !edit )
                                                        this->UpdateShipPartList();
                                                else
                                                {
                                                        m_pSelectedItem->Text = dummy->GetSection();
                                                        m_pSelectedItem->SubItems[1]->Text = dummy->GetData();
                                                }
                                        }
                                }
                                break;

                        case 5:
                                {
                                        InputBox ^input = gcnew InputBox("Enter the animation data to add", (!edit) ? "" : m_pSelectedItem->Text);
                                        input->Large();
                                        if ( input->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                                        {
                                                if ( edit )
                                                        xsp->removeAnimation(_WS(m_pSelectedItem->Text));
                                                xsp->addAnimation(_WS(input->GetInput()));
                                                this->UpdateShipPartList();
                                        }
                                }
                                break;
                 }
        }

        void PackageForm::DropGetDirectories(String ^dir, Utils::WStringList *list, bool packages)
        {
                cli::array<String ^> ^dirList = IO::Directory::GetFileSystemEntries(dir);
                for ( int j = 0; j < dirList->Length; j++ )
                {
                        if ( IO::DirectoryInfo(dirList[j]).Exists )
                                this->DropGetDirectories(dirList[j], list, packages);
                        else
                        {
                                if ( packages )
                                        list->pushBack(_WS(dirList[j]), L"-1");
                                else
                                        list->pushBack(_WS(dirList[j]), Utils::WString::Number(SPK::GetAutomaticFiletype(_WS(dirList[j]), NULL,false)));
                        }
                }
        }

        void PackageForm::RemoveSelectedFiles()
        {
                CLinkList<C_File> removeFiles;
                for ( int i = 0; i < ListFiles->SelectedItems->Count; i++ )
                {
                        int id = _WS(cli::safe_cast<System::String ^>(this->ListFiles->SelectedItems[i]->Tag)).toInt();
                        C_File *file = m_pPackage->GetFileList()->Get(id);
                        if ( m_pDisplayFile == file )
                                m_pDisplayFile = NULL;
                        removeFiles.push_back(file);
                }

                if ( removeFiles.size() )
                {
                        for ( C_File *f = removeFiles.First(); f; f = removeFiles.Next() )
                                m_pPackage->removeFile(f);
                        m_pPackage->updateSigned(false);
                        this->UpdateFileList();
                        this->UpdateDisplayPic();
                        this->UpdateChanged();
                }

                if ( !ListFiles->SelectedItems->Count )
                        this->ButRemoveFile->Enabled = false;
        }

        String ^PackageForm::ExtractImport(String ^file, String ^type)
        {
                if ( String::Compare(IO::FileInfo(file).Extension, ".xml") == 0 )
                        return file;
                
                if ( String::Compare(IO::FileInfo(file).Extension, ".pck") == 0 )
                {
                        C_File F(_WS(file));
                        F.UnPCKFile();
                        if ( F.writeToFile(CPackages::tempDirectory() + L"/tmp.dat"))
                                return _US(CPackages::tempDirectory() + L"/tmp.dat");
                }
                else if ( String::Compare(IO::FileInfo(file).Extension, ".cat") == 0 )
                {
                        CCatFile cat;
                        if ( cat.open(_WS(file), L"", CATREAD_CATDECRYPT, false) == CATERR_NONE )
                        {
                                if ( cat.extractFile(_WS("types\\" + type + L".pck"), CPackages::tempDirectory() + L"/tmp.dat"))
                                        return _US(CPackages::tempDirectory() + L"/tmp.dat");
                        }
                }

                return "";
        }

        CGameDirectories *PackageForm::gameDirectories()
        {
                return ((Form1 ^)this->MdiParent)->gameDirectories();
        }

        void PackageForm::ImportData(String ^file, int type)
        {
                CFileIO F(_WS(file));
                if ( !F.exists() )
                        return;

                std::vector<Utils::WString> lines;
                if(!F.readLines(lines))
                        return;

                LoadShip ^load = gcnew LoadShip();

                int entryPos = 1;
                int dataPos = 1;
                int dataPos2 = 0;
                bool sections = false;
                Utils::WString section;
                switch ( type )
                {
                        case 2:
                                entryPos = 2;
                                dataPos = 19;
                                load->Cockpits();
                                break;
                        case 3:
                                dataPos2 = 2;
                                load->CutData();
                                break;
                        case 4:
                                sections = true;
                                entryPos = 2;
                                load->Bodies();
                                break;
                        case 1:
                                sections = true;
                                entryPos = 2;
                                dataPos = -1;
                                load->Dummies();
                                break;
                        case 0:
                                sections = true;
                                entryPos = 2;
                                dataPos = -1;
                                load->Components();
                                break;
                }

                int entries2 = 0;
                int entries = -1;
                Utils::WStringList list;
                Utils::WString data;
                int e = 0;
                for(auto itr = lines.begin(); itr != lines.end(); itr++)
                {
                        Utils::WString str = itr->remove(9).remove('\r');
                        str = str.removeFirstSpace();
                        if (str.empty())
                                continue;
                        if (str[0] == '/')
                                continue;

                        if ( entries == -1 || (entries <= 0 && sections) )
                        {
                                entries = str.token(L";", entryPos).toInt();
                                if ( sections )
                                {
                                        section = str.token(L";", 1);
                                        load->AddGroup(_US(section));
                                }
                        }
                        else
                        {
                                if ( type == 4 )
                                {
                                        std::vector<Utils::WString> strs;
                                        if(str.tokenise(L";", strs))
                                        {
                                                for (size_t i = 0; i < strs.size(); i++ )
                                                {
                                                        strs[i].removeFirstSpace();
                                                        if ( strs[i].empty() ) continue;
                                                        Utils::WString id = strs[i].token(L";", dataPos);
                                                        load->AddShip(_US(id), "");
                                                        list.pushBack(id, Utils::WString::Number(e) + L" " + section + L";" + strs[i]);
                                                        ++e;
                                                        --entries;
                                                }
                                        }
                                }
                                else if ( type == 0 )
                                {
                                        if ( entries2 )
                                        {
                                                load->AddShip(_US(data), _US(str));
                                                list.pushBack(data, section + L";" + data + L";" + str);
                                                --entries2;
                                        }
                                        else
                                        {
                                                data = str.token(L";", 1);
                                                entries2 = str.token(L";", 2).toInt();
                                                ++e;
                                                --entries;
                                        }
                                }
                                else
                                {
                                        Utils::WString id;
                                        if ( dataPos == -1 )
                                                id = str; 
                                        else
                                                id = str.token(L";", dataPos); 

                                        if ( dataPos2 )
                                                load->AddShip(_US(id), _US(str.token(L";", dataPos2)));
                                        else
                                                load->AddShip(_US(id), "");
                                        if ( sections )
                                                list.pushBack(id, Utils::WString::Number(e) + L" " + section + L";" + str);
                                        else
                                                list.pushBack(id, Utils::WString::Number(e) + L" " + str);
                                        ++e;
                                        --entries;
                                }
                        }
                }

                if ( load->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                {
                        for(auto itr = load->GetDataList()->begin(); itr != load->GetDataList()->end(); itr++)
                        {
                                Utils::WString data = list.findString((*itr)->str);
                                if (!data.empty())
                                {
                                        switch ( type )
                                        {
                                                case 0:
                                                        ((CXspFile *)m_pPackage)->addComponent(data.token(L";", 1), data.token(L";", 2), data.tokens(L";", 3));
                                                        break;
                                                case 2:
                                                        ((CXspFile *)m_pPackage)->addCockpit(data.tokens(L" ", 2), 0, -1, data.token(L" ", 1).toInt());
                                                        break;
                                                case 3:
                                                        ((CXspFile *)m_pPackage)->addCutData(data.tokens(L" ", 2));
                                                        break;
                                                case 4:
                                                        ((CXspFile *)m_pPackage)->addBodies(data.tokens(L" ", 2));
                                                        break;
                                                case 1:
                                                        ((CXspFile *)m_pPackage)->addDummy(data.tokens(L" ", 2).token(L";", 1), data.tokens(L" ", 2).tokens(L";", 2));
                                                        break;
                                        }
                                }
                        }

                        this->UpdateShipPartList();
                        this->UpdateChanged();
                }
        }

        void PackageForm::ImportAnimations(String ^file)
        {
                CFileIO F(_WS(file));
                if ( !F.exists() )
                        return;

                Utils::WStringList lines;
                if(!F.readLines(lines))
                        return;

                Utils::WStringList lOut;
                if ( CXspFile::ReadAnimations(lines, lOut, 0) )
                {
                        LoadShip ^load = gcnew LoadShip();
                        load->Animations();
                        for(auto itr = lOut.begin(); itr != lOut.end(); itr++)
                                load->AddShip(_US((*itr)->str), "");

                        if ( load->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                        {
                                ((CXspFile *)m_pPackage)->addAnimation(*load->GetDataList());
                                this->UpdateShipPartList();
                                this->UpdateChanged();
                        }
                }
        }

        void PackageForm::EditGlobal()
        {
                AddGlobal^ global = gcnew AddGlobal();
                global->SetEdit(m_pSelectedItem->Text, m_pSelectedItem->SubItems[1]->Text);

                if (global->ShowDialog(this) == Windows::Forms::DialogResult::OK)
                {
                        m_pPackage->removeGlobal(_WS(global->GetName()));
                        m_pPackage->addGlobal(_WS(global->GetName()), _WS(global->GetData()));

                        this->UpdateGlobals();
                        this->UpdateChanged();
                }

                this->UpdateDependacies();
                this->UpdateChanged();
        }

        void PackageForm::AddNewGlobal()
        {
                AddGlobal^ global = gcnew AddGlobal();
                if (global->ShowDialog(this) == Windows::Forms::DialogResult::OK)
                {
                        m_pPackage->addGlobal(_WS(global->GetName()), _WS(global->GetData()));
                        this->UpdateGlobals();
                        this->UpdateChanged();
                }
        }

        void PackageForm::EditDepend()
        {
                 AddDepend ^depend = gcnew AddDepend();
                 depend->SetEdit(m_pSelectedItem->Text, m_pSelectedItem->SubItems[1]->Text, m_pSelectedItem->SubItems[2]->Text);

                 bool builtin = false;
                 if ( String::Compare("<package>", m_pSelectedItem->Text) == 0 && String::Compare("<author>", m_pSelectedItem->SubItems[1]->Text) == 0 )
                 {
                         builtin = true;
                         depend->BuiltIn();
                 }

                 if ( depend->ShowDialog(this) == Windows::Forms::DialogResult::OK )
                 {
                         if ( builtin )
                         {
                                 SNeededLibrary *ns = m_pPackage->findPackageNeeded(L"<package>", L"<author>");
                                 if ( ns )
                                         ns->sMinVersion = _WS(depend->GetVersion());
                         }
                         else
                         {
                                 m_pPackage->removePackageNeeded(_WS(m_pSelectedItem->Text), _WS(m_pSelectedItem->SubItems[1]->Text));
                                 m_pPackage->addNeededLibrary(_WS(depend->GetName()), _WS(depend->GetAuthor()), _WS(depend->GetVersion()));
                         }
                         this->UpdateDependacies();
                         this->UpdateChanged();
                 }
        }

        System::Void PackageForm::SetGame_Selected(System::Object^  sender, System::EventArgs^  e)
        {
                System::Windows::Forms::ToolStripMenuItem ^item = cli::safe_cast<System::Windows::Forms::ToolStripMenuItem ^>(sender);

                int done = 0;
                if (ListFiles->SelectedItems->Count)
                {
                        for (int i = 0; i < ListFiles->SelectedItems->Count; i++)
                        {
                                int id = _WS(cli::safe_cast<System::String ^>(this->ListFiles->SelectedItems[i]->Tag)).toInt();
                                C_File *file = m_pPackage->GetFileList()->Get(id);
                                if (file) {
                                        int iGame = Convert::ToInt32(item->Tag);
                                        if(!iGame)
                                                file->setGame(0);
                                        else
                                                file->setGame(1 << 31 | 1 << iGame);
                                        ++done;
                                }
                        }
                }

                if (done) {
                        this->UpdateFileList();
                        this->UpdateChanged();
                }
        }
        System::Void PackageForm::AddGame_Selected(System::Object^  sender, System::EventArgs^  e)
        {
                System::Windows::Forms::ToolStripMenuItem ^item = cli::safe_cast<System::Windows::Forms::ToolStripMenuItem ^>(sender);

                int done = 0;
                if (ListFiles->SelectedItems->Count)
                {
                        for (int i = 0; i < ListFiles->SelectedItems->Count; i++)
                        {
                                int id = _WS(cli::safe_cast<System::String ^>(this->ListFiles->SelectedItems[i]->Tag)).toInt();
                                C_File *file = m_pPackage->GetFileList()->Get(id);
                                if (file) {
                                        int iGame = Convert::ToInt32(item->Tag);
                                        if (iGame)
                                                file->setGame(file->game() | 1 << iGame | 1 << 31);
                                        ++done;
                                }
                        }
                }

                if (done) {
                        this->UpdateFileList();
                        this->UpdateChanged();
                }
        }
        System::Void PackageForm::RemoveGame_Selected(System::Object^  sender, System::EventArgs^  e)
        {
                System::Windows::Forms::ToolStripMenuItem ^item = cli::safe_cast<System::Windows::Forms::ToolStripMenuItem ^>(sender);

                int done = 0;
                if (ListFiles->SelectedItems->Count)
                {
                        for (int i = 0; i < ListFiles->SelectedItems->Count; i++)
                        {
                                int id = _WS(cli::safe_cast<System::String ^>(this->ListFiles->SelectedItems[i]->Tag)).toInt();
                                C_File *file = m_pPackage->GetFileList()->Get(id);
                                if (file) {
                                        int iGame = Convert::ToInt32(item->Tag);
                                        if (iGame)
                                                file->setGame(file->game() & ~(1 << iGame));
                                        ++done;
                                }
                        }
                }

                if (done) {
                        this->UpdateFileList();
                        this->UpdateChanged();
                }
        }
}