// UI
objref hBoxFrapLine, vBoxFrapLineControls, frapioniPlot, graphFrapLine
// Concentration file
objref fileFrapLineConcentration
// Sections affected by FRAP
objref frapLineSections[SizeTotal*2]

// Finds sections within a line and sets initial FRAP concentration on them.
// $1 - AlphaX - line equation parameter
// $2 - Y_Coor - line equation parameter
// $3 - Line width
// $4 - Basic concentration. The parameter can modulate the initial concentration of interest.
// $5 - Alpha - affects speed of the bleaching
// $6 - DFree
proc setInitialLineConcentration() { local i
    frapLineSectionsSize = 0
   
    forall {
        frapion0_FRAP = $4      // mM, The concentration of molecules used for the FRAP
        DFree_FRAP = $6

        // Find sections within a line
        if (($1*x3d(1)+$2 < y3d(1)) && (($1*x3d(1)+$2+$3*sqrt(1+$1^2)) > y3d(1))) {
		//print x3d(1)
            frapLineSections[frapLineSectionsSize] =  new SectionRef()
            frapLineSectionsSize += 1

            Alpha_FRAP = $5*$4
        }
    }
}

// Runs FRAP Line simulation.
// Bleaching during iterationTime with a constant Alpha_FRAP and recovery during the same time.
proc runFrapLine() {
    fileFrapLineConcentration = new File()
    fileFrapLineConcentration.aopen("Text results/TimeFRAP.txt")
    fileFrapLineConcentration.printf("Time\tConcentration\n")

    setInitialLineConcentration(AlphaX, Y_Coor, LineWidth, BasicFRAP, AlphaFRAP, DFreeFRAP)
    run()

    fileFrapLineConcentration.close()
}

// Updates simulation time according to the number of iterations and their time.
proc updateTstop() {
    tstop = iterations*iterationTime*2
}

// Inits UI and simulation parameters.
proc initParamsFrapLine() {
    LineWidth = 1.5     // um, bleaching line width
    AlphaX = 2          // um, the angle of inclination of a straight line
    Y_Coor = -20        // y = Alpha*x+ Y_Coor
    BasicFRAP = 0.2
    DFreeFRAP = 0.3     // (um2/ms)
    AlphaFRAP = 0.0001  // mM/ms
    iterations = 4
    iterationTime = 1000  // ms, This time parameter is necessary to reproduce the experimental course (Figure 2)
    updateTstop()
}

// Shows FRAP Line UI.
proc showFrapLineUi() { localobj plotShapeFrapioniLine
    hBoxFrapLine = new HBox()
    hBoxFrapLine.intercept(1)
    {
        vBoxFrapLineControls = new VBox()
        vBoxFrapLineControls.intercept(1)
        {
            xpanel("")
            xlabel("====================== Initial parameters ======================")
            xlabel("Coordinates of first bleaching linear area are calculated")
            xlabel("accourding to formula y = Alpha * x + Y_Coor")
            xlabel("---------------------------------------------------------------------------------------------------------------------")
            xlabel("Width of linear bleaching area in um")
            xvalue("Line width (um) ","LineWidth", 1, "", 0, 1)
            xlabel("Angle of incidence of linear bleaching in tan X-Y coordinate")
            xvalue("Alpha (um)","AlphaX", 1, "", 0, 1)
            xlabel("Position of bleaching at x = 0")
            xvalue("Y-axis intersect, Y(X=0) (um)","Y_Coor", 1, "", 0, 1)
            xlabel("---------------------------------------------------------------------------------------------------------------------")
            xlabel("Initial indicator  concentration")
            xvalue("Indicator concentration (mM)","BasicFRAP", 1, "", 0, 1)
            xlabel("Photobleaching rate")
            xvalue("Rate (mM/ms)","AlphaFRAP", 1, "", 0, 1)
            xvalue("DFree (um2/ms)","DFreeFRAP", 1, "", 0, 1)
            xlabel("===========================================================")
            xpanel(0)

            xpanel("")
            xlabel("========================== Running ==========================")
            xvalue("Duration of bleaching (recovery)","iterationTime", 1, "updateTstop()", 0, 1)
            xvalue("Bleaching-recovery iterations","iterations", 1, "updateTstop()", 0, 1)
            xlabel("Run simulation. Results are saved to the TimeFRAP.txt")
            xbutton("Run FRAP", "runFrapLine()")
            xlabel("===========================================================")
            xpanel()

            removeIfExists(flush_list, graphFrapLine)
            graphFrapLine = new Graph()
            flush_list.append(graphFrapLine)
            graphFrapLine.size(-40, 40, 0.85*BasicFRAP, 1*BasicFRAP)
            graphFrapLine.xaxis()
			graphFrapLine.label(0.0340357, 0.94, "Concentration (mM)", 2, 1, 0, 0, 1)
             graphFrapLine.label(0.45, 0.01, "Distance (um)", 2, 1, 0, 0, 1)
            frapioniPlot = new RangeVarPlot("frapioni")
            dendrite[10] frapioniPlot.begin(0)
            dendrite[1] frapioniPlot.end(1)

            graphFrapLine.addobject(frapioniPlot, 1, 1, 1, 1)
        }
        vBoxFrapLineControls.intercept(0)
        vBoxFrapLineControls.map()

        removeIfExists(fast_flush_list, plotShapeFrapioniLine)
        plotShapeFrapioniLine = new PlotShape(0)
        fast_flush_list.append(plotShapeFrapioniLine)
        plotShapeFrapioniLine.size(-50,50,-50,50)
        plotShapeFrapioniLine.view(-50, -50, 100, 100, 165, 169, 400.64, 400.32)
        plotShapeFrapioniLine.exec_menu("Shape Plot")
        plotShapeFrapioniLine.variable("frapioni")
        plotShapeFrapioniLine.show(0)
        plotShapeFrapioniLine.scale(0.8*BasicFRAP, 1.0*BasicFRAP)
		plotShapeFrapioniLine.label(0.0340357, 0.94, "Concentration (mM)", 2, 1, 0, 0, 1)
           
    }
    hBoxFrapLine.intercept(0)
    hBoxFrapLine.map("Frap In Line")
}

// Opens FRAP Line simulation window.
proc FrapLine() {
    initParamsFrapLine()
    showFrapLineUi()
}