import cv2
import json
import numpy as np
import os

# --- 1. FUNGSI LOAD KUNCI DARI TXT ---
def load_kunci_dari_txt(filename):
    mapping = {'A': 0, 'B': 1, 'C': 2, 'D': 3}
    kunci_list = []
    
    if not os.path.exists(filename):
        print(f"Error: File {filename} tidak ditemukan!")
        return None

    with open(filename, 'r') as f:
        lines = f.readlines()
        for line in lines:
            line = line.strip()
            if not line: continue
            
            # Ambil bagian setelah titik (misal '1. C' jadi 'C')
            if '.' in line:
                jawaban_raw = line.split('.')[1].strip()
            else:
                jawaban_raw = line.strip()
            
            # Pecah jika ada koma (Multi-jawaban)
            jawaban_split = jawaban_raw.split(',')
            
            # Konversi ke index (0,1,2,3)
            index_jawaban = [mapping[j.strip().upper()] for j in jawaban_split if j.strip().upper() in mapping]
            kunci_list.append(index_jawaban)
            
    return kunci_list

# Load Kunci
KUNCI_ASLI = load_kunci_dari_txt('kunci.txt')

if KUNCI_ASLI is None or len(KUNCI_ASLI) < 15:
    print("Pastikan kunci.txt berisi minimal 15 baris jawaban!")
    exit()

# --- 2. LOAD DATA KALIBRASI ---
try:
    with open('kunci_statis.json', 'r') as f:
        titik_omr = json.load(f)
except:
    print("Error: File 'kunci_statis.json' tidak ditemukan.")
    exit()

# Setting awal
offset_x, offset_y = 255, 385
SCALER = 40 
box_w, box_h = int(20 * SCALER), int(5.7 * SCALER)
rotation_state = 2 

# HITUNG KOORDINAT RELATIF
titik_relatif = [(x - 100, y - 20) for (x, y) in titik_omr]

# --- 3. KONFIGURASI WEBCAM ---
cap = cv2.VideoCapture(0, cv2.CAP_DSHOW)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 720)

while True:
    success, frame = cap.read()
    if not success: break

    if rotation_state == 1:
        frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
    elif rotation_state == 2:
        frame = cv2.rotate(frame, cv2.ROTATE_180)
    elif rotation_state == 3:
        frame = cv2.rotate(frame, cv2.ROTATE_90_COUNTERCLOCKWISE)

    img = frame.copy()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(gray, 120, 255, cv2.THRESH_BINARY_INV)

    cv2.rectangle(img, (offset_x, offset_y), (offset_x + box_w, offset_y + box_h), (255, 0, 0), 2)

    total_benar = 0
    
    # Looping hanya sampai jumlah kunci yang ada di TXT (max 15)
    jml_soal = min(len(KUNCI_ASLI), 15)
    
    for i in range(jml_soal): 
        idx_awal = i * 4
        current_coords = []
        for rx, ry in titik_relatif[idx_awal : idx_awal + 4]:
            current_coords.append((offset_x + rx, offset_y + ry))
        
        kehitaman = []
        for (x, y) in current_coords:
            y1, y2 = max(0, y-6), min(img.shape[0], y+6)
            x1, x2 = max(0, x-6), min(img.shape[1], x+6)
            roi = thresh[y1:y2, x1:x2]
            kehitaman.append(cv2.countNonZero(roi))
        
        user_ans = np.argmax(kehitaman)
        if kehitaman[user_ans] > 35:
            is_correct = (user_ans in KUNCI_ASLI[i])
            color = (0, 255, 0) if is_correct else (0, 0, 255)
            if is_correct: total_benar += 1
            cv2.circle(img, current_coords[user_ans], 12, color, 2)
        
        for k in KUNCI_ASLI[i]:
            cv2.circle(img, current_coords[k], 3, (0, 255, 255), -1)

    # --- UI INFORMASI ---
    skor_akhir = round((total_benar / jml_soal) * 100, 1)
    
    cv2.rectangle(img, (0, 0), (350, 45), (0, 0, 0), -1)
    cv2.putText(img, f"POS: {offset_x},{offset_y} | ROT: {rotation_state*90} deg", (10, 30), 
                cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 1)

    bg_x1, bg_y1 = offset_x + 400, offset_y - 5
    bg_x2, bg_y2 = offset_x + 800, offset_y - 50
    cv2.rectangle(img, (bg_x1, bg_y1), (bg_x2, bg_y2), (0, 0, 0), -1)
    
    text_skor = f"BENAR: {total_benar}/{jml_soal} | NILAI: {skor_akhir}"
    cv2.putText(img, text_skor, (offset_x + 410, offset_y - 20), 
                cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 255, 0), 2)

    cv2.imshow("Scanner SMPN 2 - Kunci TXT", img)
    
    key = cv2.waitKey(1) & 0xFF
    if key == ord('q'): break
    elif key == ord('w'): offset_y -= 5
    elif key == ord('s'): offset_y += 5
    elif key == ord('a'): offset_x -= 5
    elif key == ord('d'): offset_x += 5
    elif key == ord('r'): rotation_state = (rotation_state + 1) % 4

cap.release()
cv2.destroyAllWindows()