public SaveState CreateNewSave(User user)
        {
            string saveID = !string.IsNullOrEmpty(user.saveID) ? user.saveID : LocalSaveID;

            m_saveData         = new SaveData(saveID);
            m_saveData.Version = m_version;
            //Clear the cloud status as we are making a local change that we want to have conflict with the cloud regardless of if it thinks we synced before
            ClearCloudSyncStatus(user);
            return(m_saveData.Save(false));
        }
        public SaveState SaveToDisk()
        {
            SaveState state = SaveState.Disabled;

            //Only save if we can and we are allowed!
            if (m_saveData != null && m_savingEnabled)
            {
                state = m_saveData.Save();
            }

            return(state);
        }
        private bool OverrideLocalSave(SaveData cloudSave, SaveData localSave)
        {
            bool successful = false;
            //Try save the cloud save
            SaveState state = cloudSave.Save(false);

            if (state == SaveState.OK)
            {
                if (cloudSave.Load() == LoadState.OK)
                {
                    successful = true;
                }
            }
            //If cloud save failed save the local again
            if (!successful)
            {
                localSave.Save();
            }
            return(successful);
        }
        private void ResolveConflict(ConflictResult result, SaveData localSave, SaveData cloudSave)
        {
            LoadState cloudState;

            switch (result)
            {
            case ConflictResult.Cloud:
                Debug.Log("SaveGameManager (ResolveConflict) :: Resolving conflict with cloud save!");
                if (OverrideLocalSave(cloudSave, localSave))
                {
                    m_comparator.ReconcileData(localSave, cloudSave);
                    cloudSave.Save();
                    cloudState = LoadSystems(cloudSave);
                    if (cloudState == LoadState.OK)
                    {
                        m_saveData = cloudSave;
                        m_syncCompleteCallback(null, SyncState.Successful);
                    }
                    else
                    {
                        //Reset to local
                        LoadSystems(localSave);
                        m_saveData = localSave;
                        //TODO may need more specific errors
                        m_syncCompleteCallback(new SyncError("Failed to load resolved cloud save", ErrorCodes.SaveError), SyncState.Error);
                    }
                }
                else
                {
                    m_syncCompleteCallback(new SyncError("Failed to Override Local Save", ErrorCodes.SaveError), SyncState.Error);
                }
                break;

            case ConflictResult.Local:
                Debug.Log("SaveGameManager (ResolveConflict) :: Resolving conflict with local save!");
                m_comparator.ReconcileData(localSave, cloudSave);
                localSave.Save();
                LoadState localState = LoadSystems(localSave);
                if (localState == LoadState.OK)
                {
                    UploadSave(m_syncUser, localSave, delegate(Error error)
                    {
                        if (error != null && error.GetType() != typeof(UploadDisallowedError))
                        {
                            m_syncCompleteCallback(error, SyncState.Error);
                        }
                        else
                        {
                            m_saveData = localSave;
                            m_syncCompleteCallback(null, SyncState.Successful);
                        }
                    });
                }
                else
                {
                    //TODO may need more specific errors
                    m_syncCompleteCallback(new SyncError("Failed to load resolved cloud save", ErrorCodes.SaveError), SyncState.Error);
                }

                break;

            case ConflictResult.ForceCloud:
                SyncError forceCloudError = null;
                // Make sure we reset force override as otherwise user save file will get overriden again next time
                // If the flag doesn't exist (upgrading from old save?), just ignore the exception
                try
                {
                    cloudSave["User.ForceOverride"] = false;
                    localSave["User.ForceOverride"] = false;
                }
                catch (Exception e)
                {
                    Debug.LogException(e);
                }
                if (OverrideLocalSave(cloudSave, localSave))
                {
                    cloudSave.Save();

                    cloudState = LoadSystems(cloudSave);

                    if (cloudState == LoadState.OK)
                    {
                        m_saveData = cloudSave;
                        m_saveData.Save();
                    }
                    else
                    {
                        //Reset to local
                        LoadSystems(localSave);

                        m_saveData = localSave;
                        //TODO may need more specific errors
                        forceCloudError = new SyncError("Failed to load resolved cloud save", ErrorCodes.SaveError);
                    }
                }
                else
                {
                    m_saveData      = localSave;
                    forceCloudError = new SyncError("Failed to Override Local Save", ErrorCodes.SaveError);
                }
                // Upload the new save to cloud to delete forceOverride flag
                UploadSave(m_syncUser, m_saveData, delegate(Error error)
                {
                    if (error != null)
                    {
                        m_syncCompleteCallback(error, SyncState.Error);
                    }
                    else
                    {
                        m_syncCompleteCallback(forceCloudError, forceCloudError == null ? SyncState.Successful : SyncState.Error);
                    }
                });
                break;
            }
        }
        private LoadState LoadSave(User user, out SaveData loadedData)
        {
            m_savingEnabled = false;

            string           saveID   = !string.IsNullOrEmpty(user.saveID) ? user.saveID : LocalSaveID;
            SaveData         save     = new SaveData(saveID);
            Func <LoadState> loadSave = null;

            loadSave = delegate()
            {
                LoadState loadResult = save.Load();

                switch (loadResult)
                {
                case LoadState.NotFound:
                    if (save.Key != LocalSaveID)
                    {
                        Debug.Log("SaveGameManager (LoadSave) :: Haven't found save for saveID - " + saveID + " attempting to load local.sav instead!");

                        //If the save isn't found and we aren't trying to load a local save already then try to load a local save instead
                        save = new SaveData(LocalSaveID);

                        loadResult = loadSave();

                        if (loadResult == LoadState.OK)
                        {
                            Debug.Log("SaveGameManager (LoadSave) :: Found local.sav! Converting to user save");

                            save.UpdateSavePathAndKey(SaveUtilities.GetSavePath(saveID), saveID);

                            SaveState state = save.Save();

                            //Note: possible save duplication exploit

                            if (state == SaveState.OK)
                            {
                                //Delete old local.sav when done!
                                string localSavePath = SaveUtilities.GetSavePath(LocalSaveID);

                                try
                                {
                                    if (File.Exists(localSavePath))
                                    {
                                        File.Delete(localSavePath);
                                    }

                                    // Fix for HSW-5647 - delete the backup file as well as otherwise in some cases user can get a corrupted popup
                                    string backupPath = localSavePath + ".backup";
                                    if (File.Exists(backupPath))
                                    {
                                        File.Delete(backupPath);
                                    }
                                }
                                catch (Exception e)
                                {
                                    Debug.LogWarning("SaveGameManager (LoadSave) :: Unable to delete " + localSavePath + " - " + e.Message);
                                }
                            }
                        }
                    }
                    break;
                }
                return(loadResult);
            };

            LoadState result      = loadSave();
            Action    loadSystems = delegate()
            {
                if (result == LoadState.OK)
                {
                    result = LoadSystems(save);

                    if (result == LoadState.OK)
                    {
                        m_savingEnabled = true;
                    }
                }
            };

            //Check for valid results and enable saving if we are in a valid state!
            switch (result)
            {
            case LoadState.OK:
                //Now need to check game systems can load it!
                bool upgraded = false;
                result       = UpgradeSystems(save, out upgraded);
                save.Version = m_version;
                //TODO only save on upgrade
                if (result == LoadState.OK && upgraded)
                {
                    SaveToDisk();
                }
                loadSystems();
                break;

            case LoadState.NotFound:
                Debug.Log("SaveGameManager (LoadSave) :: No save found! Creating new save!");
                //Create a new save
                result = LoadState.OK;
                loadSystems();
                save.Version = m_version;
                if (result == LoadState.OK)
                {
                    save.Save();
                }
                break;

            default:
                loadSystems();
                m_savingEnabled = false;
                break;
            }
            loadedData = save;
            return(result);
        }