import ctypes
import math
import random
import time
from random import *

import win32api
import win32con
import win32gui
from win32api import *
from win32con import *
from win32file import *
from win32gui import *
from win32ui import *


class GDI:
    @staticmethod
    def bw_screen():
        """
        Creates a black and white effect on the screen.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hdc = win32gui.GetDC(0)

        while True:
            for i in range(210):
                win32gui.BitBlt(hdc, 0, 0, sw, sh, hdc, -5, -5, win32con.NOTSRCCOPY)
            time.sleep(1.6)

    @staticmethod
    def error_screen():
        """
        Displays error icons at various positions on the screen.
        """
        hdc = win32gui.GetDC(0)
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

        x = y = 0
        while True:
            win32gui.DrawIcon(hdc, x, y, win32gui.LoadIcon(None, win32con.IDI_ERROR))
            x = x + random.randint(30, 100)
            if x >= w:
                y = y + random.randint(30, 100)
                x = 0
            if y >= h:
                x = y = 0

    @staticmethod
    def invert_screen():
        """
        Inverts the colors on the screen.
        """
        hdc = win32gui.GetDC(0)
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        while True:
            win32gui.InvertRect(hdc, (0, 0, w, h))
            time.sleep(0.5)

    @staticmethod
    def pan_screen():
        """
        Pans the screen in random directions.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hdc = win32gui.GetDC(0)
        dx = dy = 1
        angle = 0
        size = 1
        speed = 5
        while True:

            win32gui.BitBlt(hdc, 0, 0, sw, sh, hdc, dx, dy, win32con.SRCCOPY)
            dx = math.ceil(math.sin(angle) * size * 10)
            dy = math.ceil(math.cos(angle) * size * 10)
            angle += speed / 10
            if angle > math.pi:
                angle = math.pi * -1

    @staticmethod
    def rainbow_blink():
        """
        Creates random rainbow effects on the screen.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        while True:
            hdc = win32gui.GetDC(0)
            color = (
                random.randint(0, 122),
                random.randint(0, 430),
                random.randint(0, 310),
            )
            brush = win32gui.CreateSolidBrush(win32api.RGB(*color))
            win32gui.SelectObject(hdc, brush)
            win32gui.BitBlt(
                hdc,
                random.randint(-8, 8),
                random.randint(-8, 8),
                sw,
                sh,
                hdc,
                0,
                0,
                win32con.SRCCOPY,
            )
            win32gui.BitBlt(
                hdc,
                random.randint(-10, 10),
                random.randint(-10, 10),
                sw,
                sh,
                hdc,
                0,
                0,
                win32con.PATINVERT,
            )

    @staticmethod
    def screen_wavy():
        """
        Creates a wavy effect on the screen.
        """
        desktop = win32gui.GetDesktopWindow()
        hdc = win32gui.GetWindowDC(desktop)
        sw = win32api.GetSystemMetrics(0)
        sh = win32api.GetSystemMetrics(1)
        angle = 0

        while True:
            hdc = win32gui.GetWindowDC(desktop)
            for i in range(int(sw + sh)):
                a = int(math.sin(angle) * 30)
                win32gui.BitBlt(hdc, 0, i, sw, 1, hdc, a, i, win32con.SRCCOPY)
                angle += math.pi / 30
            win32gui.ReleaseDC(desktop, hdc)
            time.sleep(0.01)

    @staticmethod
    def void_screen():
        """
        Creates a void effect on the screen.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hdc = win32gui.GetDC(0)
        dx = dy = 1
        angle = 0
        size = 1
        speed = 5
        while True:

            win32gui.BitBlt(hdc, 0, 0, sw, sh, hdc, dx, dy, win32con.SRCAND)
            dx = math.ceil(math.sin(angle) * size * 10)
            dy = math.ceil(math.cos(angle) * size * 10)
            angle += speed / 10
            if angle > math.pi:
                angle = math.pi * -1

    @staticmethod
    def glitch_screen():
        """
        Creates a glitch effect on the screen.
        """
        desk = GetDC(0)
        x, y = (GetSystemMetrics(0), GetSystemMetrics(1))
        while True:
            color = (
                random.randint(0, 255),
                random.randint(0, 255),
                random.randint(0, 255),
            )
            brush = win32gui.CreateSolidBrush(win32api.RGB(*color))
            SelectObject(desk, brush)
            PatBlt(
                desk,
                random.randrange(x),
                random.randrange(y),
                random.randrange(x),
                random.randrange(y),
                PATINVERT,
            )
            DeleteObject(brush)
            time.sleep(0.02)

    @staticmethod
    def warning_screen():
        """
        Displays a warning icon randomly on the screen.
        """
        hdc = win32gui.GetDC(0)
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

        x = y = 0
        while True:
            win32gui.DrawIcon(hdc, x, y, win32gui.LoadIcon(None, win32con.IDI_WARNING))
            x = x + random.randint(30, 100)
            if x >= w:
                y = y + random.randint(30, 100)
                x = 0
            if y >= h:
                x = y = 0

    @staticmethod
    def question_screen():
        """
        Displays a question icon randomly on the screen.
        """
        hdc = win32gui.GetDC(0)
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

        x = y = 0
        while True:
            win32gui.DrawIcon(hdc, x, y, win32gui.LoadIcon(None, win32con.IDI_QUESTION))
            x = x + random.randint(30, 100)
            if x >= w:
                y = y + random.randint(30, 100)
                x = 0
            if y >= h:
                x = y = 0

    @staticmethod
    def asterisk_screen():
        """
        Displays an asterisk icon randomly on the screen.
        """
        hdc = win32gui.GetDC(0)
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

        x = y = 0
        while True:
            win32gui.DrawIcon(hdc, x, y, win32gui.LoadIcon(None, win32con.IDI_ASTERISK))
            x = x + random.randint(30, 100)
            if x >= w:
                y = y + random.randint(30, 100)
                x = 0
            if y >= h:
                x = y = 0

    @staticmethod
    def super_icon_screen():
        """
        Displays various system icons randomly on the screen.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

        hdc = win32gui.GetDC(0)

        icon_ids = [
            win32con.IDI_APPLICATION,
            win32con.IDI_ASTERISK,
            win32con.IDI_ERROR,
            win32con.IDI_EXCLAMATION,
            win32con.IDI_HAND,
            win32con.IDI_INFORMATION,
            win32con.IDI_QUESTION,
            win32con.IDI_WARNING,
            win32con.IDI_WINLOGO,
        ]

        x = y = 0
        while True:
            icon_id = random.choice(icon_ids)
            icon = win32gui.LoadIcon(None, icon_id)
            win32gui.DrawIcon(hdc, x, y, icon)

            x = x + random.randint(30, 100)
            if x >= w:
                y = y + random.randint(30, 100)
                x = 0
            if y >= h:
                x = y = 0

    @staticmethod
    def copy_screen():
        """
        Continuously copies the entire screen area and displays it without any offset.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hdc = win32gui.GetDC(0)

        while True:
            for i in range(210):
                win32gui.BitBlt(hdc, 0, 0, sw, sh, hdc, -5, -5, win32con.SRCCOPY)
            time.sleep(1.6)

    @staticmethod
    def tunnel_screen():
        """
        Creates a tunnel effect by continuously stretching and copying the screen content inwards from the edges.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        HDC = GetDC(0)
        while True:
            StretchBlt(HDC, 50, 50, sw - 100, sh - 100, HDC, 0, 0, sw, sh, SRCCOPY)
            time.sleep(0.1)

    @staticmethod
    def twisted_screen():
        """
        Apply a twisted screen effect by performing bitwise operations on the screen content.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hdc = win32gui.GetDC(0)

        NOTSRCCOPY = 0x00330008
        SRCAND = 0x008800C6

        dx1, dy1 = -3, -3
        dx2, dy2 = 1, 1
        angle = 0
        size = 1
        speed = 5
        glitch = 0

        try:
            while True:
                if glitch % 5 == 0:
                    win32gui.BitBlt(hdc, 0, 0, sw, sh, hdc, dx1, dy1, NOTSRCCOPY)
                else:
                    win32gui.BitBlt(hdc, 0, 0, sw, sh, hdc, dx2, dy2, SRCAND)

                dx1 = math.ceil(math.sin(angle) * size * 10)
                dy1 = math.ceil(math.cos(angle) * size * 10)
                dx2 = math.ceil(math.sin(angle) * size * -10)
                dy2 = math.ceil(math.cos(angle) * size * -10)
                angle += speed / 10.0
                glitch += 1

                if angle > math.pi:
                    angle = math.pi * -1

                if glitch > 10:
                    glitch = 0

                time.sleep(0.01)

        finally:
            win32gui.ReleaseDC(0, hdc)

    @staticmethod
    def rotate_screen():
        """
        Creates a rotation effect for the entire screen around a fixed radius.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hdc = win32gui.GetDC(0)

        SRCCOPY = 0x00CC0020

        angle = 0
        speed = 0.05
        radius = 10

        try:
            while True:
                angle += speed

                if angle > 2 * math.pi:
                    angle -= 2 * math.pi

                dx = math.ceil(radius * math.cos(angle))
                dy = math.ceil(radius * math.sin(angle))

                win32gui.BitBlt(hdc, 0, 0, sw, sh, hdc, dx, dy, SRCCOPY)

                time.sleep(0.01)

        finally:
            win32gui.ReleaseDC(0, hdc)

    @staticmethod
    def repeat_block_rotation():
        """
        Creates a rotation effect for small blocks of the screen.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hdc = win32gui.GetDC(0)

        SRCCOPY = 0x00CC0020

        angle = 0
        speed = 0.1
        radius = 50

        try:
            while True:
                win32gui.BitBlt(hdc, 0, 0, sw, sh, hdc, 0, 0, SRCCOPY)

                dx = math.ceil(radius * math.cos(angle))
                dy = math.ceil(radius * math.sin(angle))

                for x in range(0, sw, 100):
                    for y in range(0, sh, 100):
                        win32gui.BitBlt(
                            hdc, x + dx, y + dy, 100, 100, hdc, x, y, SRCCOPY
                        )

                angle += speed
                if angle >= 2 * math.pi:
                    angle -= 2 * math.pi

                time.sleep(0.01)

        finally:
            win32gui.ReleaseDC(0, hdc)

    @staticmethod
    def draw_random_scribble():
        """
        Drawing of random scribbles on the screen.
        """
        hdc = win32gui.GetDC(0)
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        screen_width = user32.GetSystemMetrics(0)
        screen_height = user32.GetSystemMetrics(1)
        try:
            while True:
                num_points = random.randint(5, 15)
                points = [
                    (random.randint(0, screen_width), random.randint(0, screen_height))
                    for _ in range(num_points)
                ]
                color = win32api.RGB(
                    random.randint(0, 255),
                    random.randint(0, 255),
                    random.randint(0, 255),
                )
                pen = win32gui.CreatePen(win32con.PS_SOLID, 3, color)
                win32gui.SelectObject(hdc, pen)
                win32gui.MoveToEx(hdc, points[0][0], points[0][1])
                for point in points[1:]:
                    win32gui.LineTo(hdc, point[0], point[1])
                win32gui.DeleteObject(pen)
        finally:
            win32gui.ReleaseDC(0, hdc)

    @staticmethod
    def type_text(text):
        """
        Display text at random positions on the screen
        text (str): The text to be displayed on the screen.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hwnd = win32gui.GetDesktopWindow()
        hdc = win32gui.GetDC(hwnd)
        while True:
            x, y = random.randint(0, sw), random.randint(0, sh)
            win32gui.ExtTextOut(hdc, x, y, win32con.ETO_CLIPPED, None, str(text), None)
            time.sleep(0.3)

    @staticmethod
    def flip_screen_upside_down():
        """
        Continuously flip the computer screen upside down.
        """
        user32 = ctypes.windll.user32
        user32.SetProcessDPIAware()
        hwnd = win32gui.GetDesktopWindow()
        [sw, sh] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
        hdc = win32gui.GetDC(hwnd)
        while True:
            win32gui.StretchBlt(
                hdc, 0, 0, sw, sh, hdc, 0, sh, sw, -sh, win32con.SRCCOPY
            )
            time.sleep(0.1)


class Meme:
    """
    Secret
    """

    @staticmethod
    def easter_eggs():
        import webbrowser

        url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
        webbrowser.open(url)
