from Foundation import NSPoint, NSString
from AppKit import NSObject, NSError, NSView, NSMenu, NSColor, NSEvent, NSResponder
from typing import Tuple, Any, Optional, Dict, List
from GlyphsApp import GSFont, GSLayer, GSEditViewController, GSWindowController


class GSFilterPlugin(NSObject):
	menuName: str
	actionButtonLabel: str
	def start(self) -> None: ...
	def settings(self) -> None: ...
	def filter(self, layer: GSLayer, inEditView: bool, customParameters: Any) -> None: ...
	def runFilterWithLayer_options_error_(self, layer: GSLayer, options: Optional[Dict[str, Any]], error: NSError | None) -> Tuple[bool, Optional[NSError]]: ...
	def runFilterWithLayer_error_(self, layer: GSLayer, error: NSError | None) -> Tuple[bool, Optional[NSError]]: ...
	def generateCustomParameter(self) -> str: ...

class GSToolSelect(NSResponder):
	generalContextMenus: List[Dict[str, Any]]
	def start(self) -> None: ...
	def settings(self) -> None: ...
	def defaultContextMenu(self) -> List[Dict[str, Any]]: ...
	def conditionalContextMenus(self) -> List[Dict[str, Any]]: ...
	def __file__(self) -> str: ...
	def activate(self) -> None: ...
	def deactivate(self) -> None: ...

	def foreground(self, layer: GSLayer) -> None: ...
	def background(self, layer: GSLayer) -> None: ...

	def editViewController(self) -> GSEditViewController: ...
	def windowController(self) -> GSWindowController: ...

	def selectGlyph_(self, event: NSEvent) -> None: ...


class SelectTool(GSToolSelect):
	...

class BaseFileFormatPlugin(NSObject):
	exportPath: str
	def start(self) -> None: ...
	def settings(self) -> None: ...
	def __file__(self) -> str: ...
	def toolbarIconName(self) -> str: ...
	def export(self, font: GSFont, path: str | None = None) -> Tuple[int, str]: ...
	def read(self, path: str, fonttype: str) -> GSFont: ...
	def setFont_(self, font: GSFont) -> None: ...
	def loadNib(self, nibname: str, path: str | None = None) -> None: ...

class FileFormatPlugin(BaseFileFormatPlugin):
	...
class BaseFilterWithoutDialog(GSFilterPlugin):
	...

class FilterWithoutDialog(BaseFilterWithoutDialog):
	...

class BaseGeneralPlugin(NSObject):
	def start(self) -> None: ...
	def settings(self) -> None: ...
	def logToConsole(self, log: str) -> None: ...
	def logError(self, log: str) -> None: ...
	def loadNib(self, nibname: str, path: str | None = None) -> None: ...

class GeneralPlugin(BaseGeneralPlugin):
	...

class BasePalettePlugin(NSObject):
	def start(self) -> None: ...
	def settings(self) -> None: ...
	def windowController(self) -> GSWindowController: ...
	def setWindowController_(self, windowController: GSWindowController) -> None: ...

class PalettePlugin(BasePalettePlugin):
	def logToConsole(self, message: str) -> None: ...
	def loadNib(self, nibname: str, path: Optional[str] = None) -> None: ...


class BaseReporterPlugin(NSObject):
	_controller: Optional[GSEditViewController]
	needsExtraMainOutlineDrawingForInactiveLayers: bool
	needsExtraMainOutlineDrawingForActiveLayer: bool
	menuName: str
	keyboardShortcut: str | None
	keyboardShortcutModifier: int
	drawDefaultInactiveLayers: bool
	generalContextMenus: list
	def conditionalContextMenus(self) -> List[Dict[str, Any]]: ...
	def start(self) -> None: ...
	def settings(self) -> None: ...
	def foreground(self, layer: GSLayer) -> None: ...
	def background(self, layer: GSLayer) -> None: ...

	def inactiveLayerForeground(self, layer: GSLayer) -> None: ...
	def inactiveLayerBackground(self, layer: GSLayer) -> None: ...
	def inactiveLayers(self, layer: GSLayer) -> None: ...  # compatibilty
	def preview(self, layer: GSLayer) -> None: ...
	def foregroundInViewCoords(self) -> None: ...
	def backgroundInViewCoords(self) -> None: ...
	def getScale(self) -> float: ...
	def activePosition(self) -> Optional[NSPoint]: ...
	controller: GSEditViewController

class ReporterPlugin(BaseReporterPlugin):
	def activeLayer(self) -> Optional[GSLayer]: ...
	def drawTextAtPoint(self, text: str | NSString, textPosition: NSPoint, fontSize: float = 10.0, fontColor: NSColor = NSColor.textColor(), align: str = 'bottomleft') -> None: ...
	def logToConsole(self, message: str) -> None: ...
	def logError(self, message: str) -> None: ...
	def loadNib(self, nibname: str, path: Optional[str] = None) -> None: ...
	def title(self) -> str: ...
	def getHandleSize(self) -> float: ...

class FilterWithDialog(GSFilterPlugin):
	def logToConsole(self, message: str) -> None: ...
	def loadNib(self, nibname: str, path: Optional[str] = None) -> None: ...

	def update(self) -> None: ...

class GSToolPlugin(NSObject):
	def settings(self) -> None: ...

class GlyphsFilterOffsetCurve(GSFilterPlugin):
	@classmethod
	def offsetLayer_offsetX_offsetY_makeStroke_autoStroke_position_metrics_error_shadow_capStyleStart_capStyleEnd_keepCompatibleOutlines_(
		cls,
		layer: GSLayer,
		offsetX: float,
		offsetY: float,
		makeStroke: bool,
		autoStroke: bool,
		position: float,
		metrics: List | None,  # [GSMetricStore],
		error: Any,
		shadowLayer: GSLayer | None,
		capStyleStart: int,
		capStyleEnd: int,
		keepCompatibleOutlines: bool,
	) -> int: ...

class GlyphsFilterRoundCorner(GSFilterPlugin):
	@classmethod
	def roundLayer_radius_checkSelection_visualCorrect_grid_(
		cls,
		layer: GSLayer,
		radius: float,
		checkSelection: bool,
		visualCorrect: bool,
		grid: float
	) -> None: ...


class GSPaletteView(NSView):
	def setController_(self, controller: Any) -> None: ...


def setUpMenuHelper(menu: NSMenu, items: List[Dict[str, Any]], defaultTarget: Any) -> None: ...

def pathForResource(resourceName: str, extension: str, path: Optional[str] = None) -> Optional[str]: ...
