# -*- coding: utf-8 -*-
"""把已生成的《软件测试课程设计》教学进度表填进学院进度表模板。

模板：_tpl3/进度表模板.docx（由 广东金融学院课程教学进度表模板.doc 转换）
输出：广东金融学院课程教学进度表（软件测试课程设计-周宇文）.docx

要点：
  - 保留模板的字段块、标题行与 5 列表格（周次／课程章节／教学内容／授课·学时／教学方式）；
  - 模板表格只有 12 个空行，按 17 周（第 1–16 周教学、第 17 周考核）克隆补足；
  - 表末补一行"说明"，交代学时与考核周安排。
"""
import copy
import importlib.util
import os
import sys

from docx import Document
from docx.shared import Pt
from docx.text.paragraph import Paragraph


BASE = os.path.dirname(os.path.abspath(__file__))


def _load(name, path):
    spec = importlib.util.spec_from_file_location(name, path)
    mod = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(mod)
    return mod


G = _load('gen', os.path.join(BASE, '_gen_教学文件.py'))
C = G.C


def set_text(p, text):
    if not p.runs:
        p.add_run(text)
        return
    p.runs[0].text = text
    for r in p.runs[1:]:
        r.text = ''


def set_cell(cell, text):
    while len(cell.paragraphs) > 1:
        cell.paragraphs[-1]._p.getparent().remove(cell.paragraphs[-1]._p)
    set_text(cell.paragraphs[0], str(text))
    for para in cell.paragraphs:
        for r in para.runs:
            r.font.name = '宋体'
            if r.font.size is None:
                r.font.size = Pt(10.5)


def row_cells(row):
    seen, out = set(), []
    for c in row.cells:
        if id(c._tc) in seen:
            continue
        seen.add(id(c._tc))
        out.append(c)
    return out


def week_rows():
    """从已生成的教学进度表数据里取每周一行。"""
    for b in G.doc_进度表():
        if b[0] == 'table':
            return b[1][1:]          # 去掉表头
    return []


def main():
    doc = Document(os.path.join(BASE, '_tpl3', '进度表模板.docx'))

    for p in doc.paragraphs:
        t = p.text.strip()
        if t.startswith('课程名称：'):
            set_text(p, '课程名称：' + C['name'])
        elif t.startswith('课程代码：'):
            set_text(p, '课程代码：' + C['code'])
        elif t.startswith('开课单位：'):
            set_text(p, '开课单位：' + C['college'])
        elif t.startswith('制定人：'):
            set_text(p, '制定人：' + C['teacher'])
        elif t.startswith('审核人：'):
            set_text(p, '审核人：' + C['reviewer'])
        elif t.startswith('制定时间：'):
            set_text(p, '制定时间：' + C['date'])
        elif '课 程 教 学 进 度 表' in t or '课程教学进度表' in t:
            set_text(p, '%s　课 程 教 学 进 度 表' % C['name'])
        elif t.startswith('学时：'):
            set_text(p, '学时：%d　　　　学分：%d　　　　周次：第 1–17 周（含实验）'
                     % (C['hours'], C['credits']))

    tbl = doc.tables[0]
    rows = week_rows()
    # 表格首行是表头，其余按周填；不足则克隆最后一行
    while len(tbl.rows) - 1 < len(rows):
        new = copy.deepcopy(tbl.rows[-1]._tr)
        tbl._tbl.append(new)
    while len(tbl.rows) - 1 > len(rows):
        tbl._tbl.remove(tbl.rows[-1]._tr)

    for i, data in enumerate(rows, start=1):
        cells = row_cells(tbl.rows[i])
        vals = [str(x) for x in data[:5]]
        for j, val in enumerate(vals):
            if j < len(cells):
                set_cell(cells[j], val)

    # 压缩模板里把表格顶到后面几页的空白段落（保留"教务处 制"与标题行）
    paras = doc.paragraphs
    keep_flags = []
    seen_bianzhi = False
    for p_ in paras:
        t = p_.text.strip()
        if t.startswith('广东金融学院教务处'):
            seen_bianzhi = True
        keep_flags.append(bool(t) or t.startswith('学时：') or seen_bianzhi is False)
    # 仅在"制定时间"之后、"教务处 制"之前删除空段
    start = None
    for i, p_ in enumerate(paras):
        if p_.text.strip().startswith('制定时间：'):
            start = i
            break
    if start is not None:
        for p_ in list(paras[start + 1:]):
            if p_.text.strip().startswith('广东金融学院教务处'):
                break
            if not p_.text.strip():
                p_._p.getparent().remove(p_._p)

    # 表头跨页重复
    from docx.oxml.ns import qn as _qn
    trPr = tbl.rows[0]._tr.get_or_add_trPr()
    if trPr.find(_qn('w:tblHeader')) is None:
        el = trPr.makeelement(_qn('w:tblHeader'), {})
        trPr.append(el)

    # 表末补说明
    note = Paragraph(copy.deepcopy(doc.paragraphs[-1]._p), doc.paragraphs[-1]._parent)
    doc.paragraphs[-1]._p.addnext(note._p)
    set_text(note, '说明：第 1–16 周每周 2 学时，共 32 学时；第 17 周为考核周（不计学时），'
                   '用于课程设计成果评定与成绩提交；实验任务随对应章节同步开展。')
    for r in note.runs:
        r.font.name = '宋体'
        r.font.size = Pt(10.5)

    out = os.path.join(BASE, '广东金融学院课程教学进度表（软件测试课程设计-周宇文）.docx')
    doc.save(out)
    d = Document(out)
    print('已生成：%s' % out)
    print('表格 %d 行（含表头）｜ 表格数 %d' % (len(d.tables[0].rows), len(d.tables)))
    return 0


if __name__ == '__main__':
    sys.exit(main())
