#!/usr/bin/env python3

"""
Standardized Comparison Node:
  - Compares two input values using a selected operator (==, !=, >, <, >=, <=).
  - Outputs a result of 1 (True) or 0 (False).
  - Uses a global update timer for processing.
  - Supports an additional 'Input Type' dropdown to choose between 'Number' and 'String'.
"""

from OdenGraphQt import BaseNode
from Qt import QtCore

class ComparisonNode(BaseNode):
    __identifier__ = 'bunny-lab.io.comparison_node'
    NODE_NAME = 'Comparison Node'

    def __init__(self):
        super(ComparisonNode, self).__init__()
        self.add_input('A')
        self.add_input('B')
        self.add_output('Result')

        # Add the Input Type dropdown first.
        self.add_combo_menu('input_type', 'Input Type', items=['Number', 'String'])
        self.add_combo_menu('operator', 'Operator', items=[
            'Equal (==)', 'Not Equal (!=)', 'Greater Than (>)',
            'Less Than (<)', 'Greater Than or Equal (>=)', 'Less Than or Equal (<=)'
        ])
        # Replace calc_result with a standardized "value" text input.
        self.add_text_input('value', 'Value', text='0')
        self.value = 0
        self.set_name("Comparison Node")
        self.processing = False  # Guard for process_input

        # Set default properties explicitly
        self.set_property('input_type', 'Number')
        self.set_property('operator', 'Equal (==)')

    def process_input(self):
        if self.processing:
            return
        self.processing = True
        
        # Retrieve input values; if no connection or None, default to "0"
        input_a = self.input(0)
        input_b = self.input(1)
        a_raw = (input_a.connected_ports()[0].node().get_property('value')
                 if input_a.connected_ports() else "0")
        b_raw = (input_b.connected_ports()[0].node().get_property('value')
                 if input_b.connected_ports() else "0")
        a_raw = a_raw if a_raw is not None else "0"
        b_raw = b_raw if b_raw is not None else "0"
        
        # Get input type property
        input_type = self.get_property('input_type')
        
        # Convert values based on input type
        if input_type == 'Number':
            try:
                a_val = float(a_raw)
            except (ValueError, TypeError):
                a_val = 0.0
            try:
                b_val = float(b_raw)
            except (ValueError, TypeError):
                b_val = 0.0
        elif input_type == 'String':
            a_val = str(a_raw)
            b_val = str(b_raw)
        else:
            try:
                a_val = float(a_raw)
            except (ValueError, TypeError):
                a_val = 0.0
            try:
                b_val = float(b_raw)
            except (ValueError, TypeError):
                b_val = 0.0

        operator = self.get_property('operator')
        
        # Perform the comparison
        result = {
            'Equal (==)': a_val == b_val,
            'Not Equal (!=)': a_val != b_val,
            'Greater Than (>)': a_val > b_val,
            'Less Than (<)': a_val < b_val,
            'Greater Than or Equal (>=)': a_val >= b_val,
            'Less Than or Equal (<=)': a_val <= b_val
        }.get(operator, False)
        
        new_value = 1 if result else 0
        self.value = new_value
        self.set_property('value', str(self.value))
        self.transmit_data(self.value)
        
        self.processing = False

    def on_input_connected(self, input_port, output_port):
        pass

    def on_input_disconnected(self, input_port, output_port):
        pass

    def property_changed(self, property_name):
        pass

    def receive_data(self, data, source_port_name=None):
        pass

    def transmit_data(self, data):
        output_port = self.output(0)
        if output_port and output_port.connected_ports():
            for connected_port in output_port.connected_ports():
                connected_node = connected_port.node()
                if hasattr(connected_node, 'receive_data'):
                    try:
                        data_int = int(data)
                        connected_node.receive_data(data_int, source_port_name='Result')
                    except ValueError:
                        pass