// XDrawChem
// Copyright (C) 2004-2005  Bryan Herger <bherger@users.sourceforge.net>
// Copyright (C) 2020  Yaman Qalieh <ybq987@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#include "arrow.h"
#include "bond.h"
#include "bracket.h"
#include "chemdata.h"
#include "clipboard.h"
#include "curvearrow.h"
#include "defs.h"
#include "drawable.h"
#include "molecule.h"
#include "symbol.h"
#include "text.h"

void ChemData::ScaleAll(double bond_length) {
    Molecule *tmp_mol;

    for (Drawable *tmp_draw : drawlist) {
        if (tmp_draw->Type() == TYPE_MOLECULE) {
            tmp_mol = (Molecule *)tmp_draw;
            tmp_mol->Scale(bond_length);
        }
    }
}

void ChemData::Cut() {
    Copy();
    EraseSelected();
}

void ChemData::Copy() {
    Clipboard *clipboard = getClipboard();
    clipboard->clear();

    for (Drawable *drawable : drawlist) {
        bool hl = drawable->Highlighted();
        if (drawable->Type() == TYPE_MOLECULE && !hl) {
            for (Drawable *d : drawable->AllObjects()) {
                hl = d || hl;
            }
        }

        if (hl) {
            clipboard->objects.append(drawable->CloneTo());
        }
    }
}

bool ChemData::Paste() {
    Clipboard *clipboard = getClipboard();

    if (clipboard->objects.empty()) {
        return false;
    }

    EraseSelected();
    DeselectAll();
    for (int i = 0; i < clipboard->objects.size(); ++i) {
        drawlist.append(clipboard->objects[i]);
        clipboard->objects[i] = clipboard->objects[i]->CloneTo();
    }

    return true;
}

void ChemData::StartUndo(int fn, DPoint *s1) {

    // checkpoint!
    save_native(""); // saves into current_undo_file

    // Do not save if there are no changes
    if (undo_index != -1 && last_states[undo_index] == current_undo_file) {
        current_undo_file = "";
        return;
    }

    // Erase redo history
    if (fn != 0) {
        while (last_states.size() > (undo_index + 1)) {
            last_states.removeLast();
        }
    }

    // Delete old items if it's full
    if (last_states.size() > 31) {
        last_states.removeFirst();
        --undo_index;
    }

    // Add history item
    last_states << current_undo_file;
    ++undo_index;
}

bool ChemData::Undo() {
    // No more undo items
    if (undo_index < 0) {
        return false;
    }

    // Save current state for redo if it's the last item
    if (undo_index == last_states.size() - 1) {
        StartUndo(1);
        --undo_index;
    }

    load_native(last_states[undo_index--]);
    current_undo_file = "";
    return true;
}

bool ChemData::Redo() {
    // No more redo items
    if (last_states.size() - 2 <= undo_index)
        return false;

    load_native(last_states[++undo_index + 1]);
    return true;
}
