import scribus
import os

# --------------------------------------------------
# ARCHIVO PARA RECORDAR EL ÚLTIMO TOKEN
# --------------------------------------------------
TOKEN_FILE = os.path.join(
    os.path.dirname(__file__),
    "last_geom_token.txt"
)

def load_last_token():
    if os.path.exists(TOKEN_FILE):
        try:
            with open(TOKEN_FILE, "r", encoding="utf-8") as f:
                return f.read().strip()
        except Exception:
            return ""
    return ""

def save_last_token(token):
    try:
        with open(TOKEN_FILE, "w", encoding="utf-8") as f:
            f.write(token)
    except Exception:
        pass


def main():
    if not scribus.haveDoc():
        scribus.messageBox("Error", "No hay ningún documento abierto")
        return

    # --------------------------------------------------
    # 1. ORIGEN = OBJETO SELECCIONADO
    # --------------------------------------------------
    if scribus.selectionCount() != 1:
        scribus.messageBox(
            "Error",
            "Debes seleccionar EXACTAMENTE un objeto\n"
            "(texto, imagen o forma) que actuará como origen."
        )
        return

    origin = scribus.getSelectedObject(0)
    origin_type = scribus.getObjectType(origin)

    SUPPORTED_TYPES = (
        4, 2, 5, 6, 7,
        "TextFrame", "ImageFrame",
        "Polygon", "PolyLine", "Bezier"
    )

    if origin_type not in SUPPORTED_TYPES:
        scribus.messageBox(
            "Error",
            "El objeto seleccionado no es compatible.\n\n"
            "Tipos admitidos:\n"
            "- Marcos de texto\n"
            "- Marcos de imagen\n"
            "- Rectángulos / Polígonos\n"
            "- Polilíneas\n"
            "- Curvas Bézier"
        )
        return

    ox, oy = scribus.getPosition(origin)
    ow, oh = scribus.getSize(origin)

    # --------------------------------------------------
    # 2. TOKEN (CON MEMORIA)
    # --------------------------------------------------
    last_token = load_last_token()

    token = scribus.valueDialog(
        "Sincronizar objetos",
        "Texto que deben contener los objetos destino:",
        last_token
    )

    if not token:
        scribus.messageBox("Cancelado", "No se ha introducido ningún texto.")
        return

    save_last_token(token)

    # --------------------------------------------------
    # 3. MODO DE SINCRONIZACIÓN
    # --------------------------------------------------
    mode = scribus.valueDialog(
        "Modo de sincronización",
        "AVISO:\n"
        "Este script modifica objetos dentro de capas bloqueadas.\n"
        "Se deberá bloquear uno a uno los objetos que se desee conservar intactos.\n\n"
        "MODOS DISPONIBLES:\n"
        "[all]       → posición + tamaño\n"
        "[position]  → X + Y\n"
        "[size]      → ancho + alto\n"
        "[width]     → solo ancho\n"
        "[height]    → solo alto\n"
        "[x]         → solo X\n"
        "[y]         → solo Y",
        "all"
    )

    if not mode:
        scribus.messageBox("Cancelado", "No se ha elegido modo.")
        return

    mode = mode.lower().strip()

    if mode not in ("all", "position", "size", "width", "height", "x", "y"):
        scribus.messageBox(
            "Error",
            "Modo no válido.\n"
            "Usa exactamente uno de los valores indicados."
        )
        return

    # --------------------------------------------------
    # 4. SINCRONIZACIÓN
    # --------------------------------------------------
    synced = 0
    skipped = 0
    blocked = 0
    failed = 0

    current_page = scribus.currentPage()
    scribus.setRedraw(False)

    try:
        for page in range(1, scribus.pageCount() + 1):
            scribus.gotoPage(page)

            for item in scribus.getPageItems():
                name, item_type = item[0], item[1]

                if item_type not in SUPPORTED_TYPES:
                    continue

                if token not in name:
                    continue

                if name == origin:
                    skipped += 1
                    continue

                try:
                    cx, cy = scribus.getPosition(name)
                    cw, ch = scribus.getSize(name)

                    if mode == "all":
                        scribus.moveObjectAbs(ox, oy, name)
                        scribus.sizeObject(ow, oh, name)

                    elif mode == "position":
                        scribus.moveObjectAbs(ox, oy, name)

                    elif mode == "size":
                        scribus.sizeObject(ow, oh, name)

                    elif mode == "width":
                        scribus.sizeObject(ow, ch, name)

                    elif mode == "height":
                        scribus.sizeObject(cw, oh, name)

                    elif mode == "x":
                        scribus.moveObjectAbs(ox, cy, name)

                    elif mode == "y":
                        scribus.moveObjectAbs(cx, oy, name)

                    nx, ny = scribus.getPosition(name)
                    nw, nh = scribus.getSize(name)

                    if (cx, cy, cw, ch) == (nx, ny, nw, nh):
                        blocked += 1
                    else:
                        synced += 1

                except Exception:
                    failed += 1

    finally:
        scribus.setRedraw(True)
        scribus.gotoPage(current_page)

    # --------------------------------------------------
    # 5. RESULTADO
    # --------------------------------------------------
    scribus.messageBox(
        "Sincronización completada",
        f"Origen: {origin}\n"
        f"Texto buscado: '{token}'\n"
        f"Modo: {mode}\n\n"
        f"Sincronizados: {synced}\n"
        f"Bloqueados: {blocked}\n"
        f"Omitidos (origen): {skipped}\n"
        f"Fallidos: {failed}"
    )

# --------------------------------------------------
main()
