
class URLEncoder:
    @staticmethod
    def encode(string):
        """URL encode a string without using string methods"""
        result = []
        safe_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"
        
        for char in string:
            if char in safe_chars:
                result.append(char)
            else:
                # result.append('%' + format(ord(char), '02X'))
                # Converted to % formatting:
                special_char = "%%%02X" % ord(char) 
                
                print( f"{char} --> {special_char}")
                
                result.append(special_char)
                
        return ''.join(result)    
    
    @staticmethod
    def encode_utf8(string):
        """URL encode a string with proper UTF-8 handling"""
        result = []
        safe_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"
        
        for char in string:
            if char in safe_chars:
                result.append(char)
            else:
                # UTF-8 encoding for proper URL encoding
                utf8_bytes = char.encode('utf-8')
                for byte in utf8_bytes:
                    result.append(f"%{byte:02X}")
    
        return ''.join(result)    
    
    @staticmethod
    def encode_plus(string):
        encoded = URLEncoder.encode(string)
        return encoded.replace('%20', '+')
    
    @staticmethod
    def decode(encoded_string):
        result = []
        i = 0
        while i < len(encoded_string):
            if encoded_string[i] == '%' and i + 2 < len(encoded_string):
                hex_code = encoded_string[i+1:i+3]
                result.append(chr(int(hex_code, 16)))
                i += 3
            elif encoded_string[i] == '+':
                result.append(' ')
                i += 1
            else:
                result.append(encoded_string[i])
                i += 1
        return ''.join(result)
    
    @staticmethod
    def encode_params(params):
        pairs = []
        for key, value in params.items():
            pairs.append(f"{URLEncoder.encode(str(key))}={URLEncoder.encode(str(value))}")
        return '&'.join(pairs)

