/* Rosemary.h */
	
# ifndef Rosemary
# define Rosemary

#include "CoreBasics.h"
#include "Core.h"
#include "CoreFlat.h"
	
#define RoseLevelCount 3
#define RoseDriveCount 15

#define RoseInspect 0
#define RoseExpect 1
#define RoseNone 2
#define RoseChargeWeak 3
#define RoseChargeMediumWeak 4
#define RoseCharge 5
#define RoseChargeMediumStrong 6
#define RoseChargeStrong 7
#define RoseForce 8
#define RoseDriveWeak 9
#define RoseDriveMediumWeak 10
#define RoseDrive 11
#define RoseDriveMediumStrong 12
#define RoseDriveStrong 13
#define RoseInfinite 14

/* Data Structures */
	
	typedef enum RoseLevel {L, H, X} RoseLevel;
		
	extern String RoseLevelNames[RoseLevelCount];
		
	typedef Nat RoseStrength;
		
	extern String RoseDriveNames[RoseDriveCount];
		
	typedef struct RoseProbePrimitiveRec {
		RoseLevel level;
		RoseStrength drive;
		struct RoseWireRec *wire;
		} RoseProbePrimitiveRec;
		
	typedef RoseProbePrimitiveRec *RoseProbePrimitive;
	typedef List RoseProbePrimitives;
		
	typedef struct RoseProbeRec {
		struct RoseSimulationRec *simulation;
		Nat size;
		RoseProbePrimitive elements[1];
		} RoseProbeRec;
		
	typedef RoseProbeRec *RoseProbe;
		
	typedef struct RoseTransistorRec {
		struct RoseWireRec *gate;
		struct RoseWireRec *ch1;
		struct RoseWireRec *ch2;
		RoseStrength conductivity;
		TransistorType transistorType;
		FlatCellTypeRec flatCellType;
		} RoseTransistorRec;
		
	typedef RoseTransistorRec *RoseTransistor;
	typedef List RoseTransistors;
		
	typedef struct RoseWireRec {
		struct RoseWireRec *nextPerturbedWire;
		struct RoseWireRec *previousPerturbedWire;
		struct RoseWireRec *nextRecomputed;
		struct RoseWireRec *nextVicinityWire;
		RoseProbePrimitives probes;
		RoseTransistors channels;
		RoseTransistors notOffChannels;
		RoseTransistors gates;
		RoseStrength switchDrive;
		RoseStrength upDrive;
		RoseStrength downDrive;
		RoseStrength wireSize;
		RoseLevel wireLevel;
		Bool mark;
		FlatWire flatWire;
		} RoseWireRec;
		
	typedef RoseWireRec *RoseWire;
		
	typedef struct RoseWiresRec {
		Nat size;
		RoseWire elements[1];
		} RoseWiresRec;
		
	typedef RoseWiresRec *RoseWires;
		
	typedef struct RoseVicinityRec {
		RoseWires wires;
		Nat firstFree;
		} RoseVicinityRec;
		
	typedef struct RoseSimulationRec {
		CellType cellType;
		HashTable coreToRoseWires;
		RoseWire perturbed;
		RoseVicinityRec vicinityByStrength[RoseDriveCount];
		Nat settle;
		Nat step;
		} RoseSimulationRec;
		
	typedef RoseSimulationRec *RoseSimulation;
		
/* Instantiation and Relaxation */
	
	extern void RoseInitialize();
		/*  */
		
	extern Wire RoseSetFixedWire();
		/* sameWire, Wire wire, RoseLevel level */
		
	extern Wire RoseSetNamedFixedWire();
		/* sameWire, CellType cellType, String name, RoseLevel level */
		
	extern RoseSimulation RoseInstantiate();
		/* simulation, CellType cellType */
		
	extern void RoseSettle();
		/* RoseSimulation simulation */
		
	extern RoseProbe RoseCreateProbe();
		/* probe, RoseSimulation simulation, FlatWireRec flatWire */
		
	extern RoseProbe RoseBindProbe();
		/* probe, RoseSimulation simulation, CellType cellType, String name, FlatCellTypeRec flatCell=rootCellType */
		
	 extern RoseLevel RoseGL();
		/* level, RoseProbe probe */
		
	 extern void RosePL();
		/* RoseProbe probe, RoseLevel level, Nat drive */
		
# endif