%gennemgang af selve fil formatet (bin og map)

%hvordan er model delen lavet.. contains, nearest etc

%serialize tingen

%skriv at resten ikke er int. og derfor ikke gennemgået.


\chapter{Implementering af editor}
\begin{intro}
I de følgende afsnit vil implementeringen af editoren blive gennemgået. Først vil opdelingen af editoren blive gennemgået, og derefter vil centrale dele og mønstre blive gennemgået. Mindre interessante dele som f.eks. definition af brugergrænsefladen er undladt, da det stort set kun består af API kald.
\end{intro}

Editoren er som før beskrevet opbygget efter MVC-mønsteret. Da dette lægger op til en klar adskillelse imellem data og fremvisningen af denne er editoren opdelt i 3 pakker.
\begin{itemize}
    \item UI (User Interface)
    \item Model
    \item Export
\end{itemize}


Model-pakken repræsenterer data i editoren. Klasserne i ui-pakken indeholder alt, hvad der har med visning af data, samt brugerinteraktion at gøre. Model er pakken som navnet antyder  modellen, og ui-pakken er både controller og view. \texttt{Export} pakken er et view af dataen i XML.

Jfr. figur \ref{fig:editoruidetail} på side \pageref{fig:editoruidetail}. \texttt{BlasterEditor} er et \texttt{JFrame}, der indeholder min 3 vinduer indeni sig. Derudover er der en normal menubjælke, der har knapper til at indlæse, gemme og eksportere banen.
De tre vinduer er:
\begin{enumerate}
    \item Et view af banen (\texttt{MapFrame})
    \item Knapper til at skifte tilstand (\texttt{FloatingToolBar})
    \item En liste over egenskaber (\texttt{PropertyFloat})
\end{enumerate} 
Først et view af selve banen. Vinduet er implementeret i \texttt{MapFrame} der nedarver fra \texttt{JInternalFrame}. Indholdet af vinduet bliver optegnet af \texttt{EditorCanvas} der er implementeret som et \texttt{JPanel}.

Editoren kan skifte imellem forskellige tilstande(Modes). Hver af disse tilstande er implementeret som en klasse. I den nuværende implementering af editoren er der 2 tilstande: én til at tegne polygoner samt én til at flytte elementer i banen. Når editoren er i polygon-tilstand kan brugeren tegne polygoner, og i flytnings-tilstand kan hele polygoner flyttes. 

\texttt{Modelpakken} arbejder med model-dataen i editoren.
Editoren arbejder med kanter, polygoner og punkter. Disse bliver repræsenteret af hver sin klasse:
\begin{itemize}
    \item Kanter repræsenteret ved klasssen \texttt{Edge}
    \item Tresidede polygoner repræsenteret ved klasssen \texttt{Triangle}
    \item Punkter repræsenteret ved klasssen \texttt{Vertex}
\end{itemize}
Klassen \texttt{Map} repræsenterer banen som en helhed. Den indeholder lister af de punkter og trekanter, der indgår i banen, samt informationer om selve banen, så som højde og bredde. Samtlige klasser i model-pakken nedarver fra EditorObject (EditorObject selv undtaget), af hensyn til at have et fælles interface til at håndtere egenskaber for elementerne.

Export-pakken indeholder en enkelt klasse, exporter. \texttt{exporter} bruges til at eksportere en bane ud i et XML-format, der senere kan indlæses af spillet. 

\section{Centrale dele}

\begin{figure}[h]
\begin{center}
    \begin{minipage}[t]{\textwidth}
        \begin{center}
            \scalebox{0.5}{\includegraphics{gfx/editoruidetail.pdf}}
            \caption{Klasserne i ui-pakken}
            \label{fig:editoruidetail}
        \end{center}
    \end{minipage}
\end{center}
\end{figure}

\begin{figure}[h]
\begin{center}
    \begin{minipage}[t]{\textwidth}
        \begin{center}
            \scalebox{0.5}{\includegraphics{gfx/editormodeldetail.pdf}}
            \caption{Klasserne i model-pakken}
            \label{fig:editmodeldetail}
        \end{center}
    \end{minipage}
\end{center}
\end{figure}


\subsection{Baneelementer}
Banen består af kanter, punkter og polygoner. Disse objekter har en række ting til fælles.
\begin{itemize}
    \item De kan flyttes
    \item De har tilknyttet egenskaber så som farve og størrelse
    \item De kan vælges
\end{itemize}
Det er derfor oplagt at lade den nedarve fra en fælles baseklasse. \texttt{EditorObject} er en abstrakt klasse der indeholder den funktionalitet som baneelementerne deler. Jfr. figur \ref{fig:editmodeldetail} på side \pageref{fig:editmodeldetail}

Metoder bane-elementer deler:
\begin{description}
    \item[\texttt{setProperties} og \texttt{getProperties}] metoderne bruges til at få adgang til en liste af egenskaber tilknyttet objektet.
    \item[\texttt{move}] metoden flytter objektet til et givet koordinatsæt.
    \item[\texttt{select}] metoden sætte objektet til at være valgt eller ikke valgt.
    \item[\texttt{bounds}] metoden returnerer et rektangel, der omslutter objektet.
    \item[\texttt{updateOnDrag}] returnerer et rektangel, der angiver hvilket område på skærmen, der skal opdateres efter at en objekt er blevet flyttet.
\end{description}
Map nedarver også fra \texttt{EditorObject}. Dette er gjort fordi \texttt{Map} indeholder en række egenskaber som navn og størrelse. \texttt{move} og \texttt{updateOnDrag} metoderne fra \texttt{EditorObject} er overskrevet med tomme metoder, da brugeren ikke skal kunne flytte et map.

\subsection{Præsentation af modellen}
\subsubsection{Brugergrænseflade}
\texttt{EditorCanvas} sørger for den egentlige tegning af banen ved at kalde \texttt{draw} metoden i \texttt{Map}. Denne metode beder hvert element i banen om at tegne sig selv til {EditorCanvas}' kontekst.

\subsubsection{Eksportering}
Klassen \texttt{Exporter} kan eksportere banen fra editoren ud i et XML-format. Selve eksporteringen sker v.h.a. Java-pakken \texttt{ElectricXML}. Den er valgt da den er meget let at arbejde med. Hvis ikke programmet skulle understøtte mange platforme kunne man med fordel have brugt Javas egen XML parser, der er med i alle versioner efter 1.4.0. Der er dog endnu ingen 1.4 version til Mac OS X. 

Den resulterende XML-fil indeholder data fra banen, struktureret på stort set samme måde som den er struktureret i editoren:
\begin{itemize}
    \item En liste over punkter, hvor hvert punkt tildeles et fortløbende nummer.
    \item En liste over polygoner, hvor hver polygon tildeles et fortløbende nummer.
    \item For hver polygon: en liste over kanter
    \item For hver kant: referencer til de to punkter som kanten er dannet af.
Jfr figur \ref{fig:editoruidetail}
\end{itemize}

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for eksportering af Map, label=lst:export]
tilføj ny map-rod

tilføj ny punkt-rod til map-rod
for hvert punkt i map
    tilføj punkt til punkt-rod

tilføj ny polygons-rod
for hver polygon i map
    tilføj ny polygon-rod
    for hver kant i polygon
        find id for start/slutpunkt
        tilføj punkt til polygon-rod
eksporter fil
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

En eksporteret XML fil for en bane med to polygoner kan se således ud:

\begin{verbatim} 
<?xml version='1.0' encoding='UTF-8'?>
<map width='1000.0' height='1000.0' 
     gravityx='0.0' gravityy='0.0' name=''\>
  <points size='6'>
    <point x='47.0' y='-87.0' id='0'/>
    <point x='109.0' y='-45.0' id='1'/>
    <point x='52.0' y='-33.0' id='2'/>
    <point x='126.0' y='-46.0' id='3'/>
    <point x='128.0' y='-102.0' id='4'/>
    <point x='63.0' y='-100.0' id='5'/>
  </points>
  <polygons size='2'>
    <polygon id='0'>
      <color r='1.0' g='1.0' b='1.0'/>
      <edge p1='0' platform='false' id='0'/>
      <edge p1='2' platform='false' id='1'/>
      <edge p1='1' platform='false' id='2'/>
    </polygon>
    <polygon id='1'>
      <color r='1.0' g='1.0' b='1.0'/>
      <edge p1='3' platform='false' id='0'/>
      <edge p1='4' platform='false' id='1'/>
      <edge p1='5' platform='false' id='2'/>
    </polygon>
  </polygons>
</map>
\end{verbatim}

\subsection{Gem bane fra editor}

Da editoren har brug for flere informationer om banen end spillet, blev det besluttet at lave to formater. Spillets eget format er en simpel serialisering af Java objektet \texttt{Map}. Der er ikke taget stilling til hvilke felter der skal serialiseres. Der er bare benyttet Java standard serialisering ved at implementere Serializable interfacet. Dette gør det meget nemt både at gemme og hente banen ind igen, men svært at bruge banen i andre programmer. Men man slipper for at skrive parsere til et filformat.

\subsection{Tilstande}

Muligheden for at skifte tilstande i editoren er implementeret som et Strategy mønster. Der er dermed mulighed, for at implementere vilkårligt mange tilstande i editoren. 

Jfr. figur \ref{fig:editoruidetail} på side \pageref{fig:editoruidetail}. Alle tilstands-objekter nedarver fra den abstrakte klasse \texttt{AbstractMode}. \texttt{AbstractMode} indeholder abstrakte metoder til at håndtere input fra brugeren, som det konkrete objekt skal implementere. \texttt{MapFrame} indeholder en reference til det nuværende tilstands-objekt, af typen \texttt{AbstractMode}. 

MapFrame bruger sit AbstractMode til at håndtere input fra brugeren. Dermed bestemmer den aktuelle tilstands-objekt, hvordan editoren reagerer på input.

\subsubsection{Polygon-tilstand}
Polygon-tilstand(PolygonMode) bruges til at tegne nye polygoner.

I polygon-tilstand reagere editoren på følgende måde:
\begin{itemize}
    \item Hvis brugeren klikker på et vilkårligt sted på banen, tilføjes der et nyt punkt på det pågældende sted.
    \item Når det tredje punkt tilføjes, oprettes der en ny trekant bestående af disse 3 punkter.
    \item Hvis et nyt punkt sættes inden for en minimumsafstand af et eksisterende punkt samles de to til et punkt
\end{itemize}

For at tilføje et punkt afsættes tre punkter på en \texttt{MapFrame}. For hver gang et punkt indsættes i den interne liste af punkter undersøges det om der er kommet tre punkter siden sidste polygon blev dannet. Hvis dette er tilfældet dannes en ny polygon. Alt dette forgår i \texttt{PolygonMode} klassen. Dette er illustreret i den følgende pseudo kode:
\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for tilføjelse af punkt, label=lst:addVertex]
tilføj punkt til Map's punkt-liste

hvis antal i Map's punkt-liste = 3
    trekant = lav trekant fra punktliste
    tilføj trekant til map
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}
Hvis et nyt punkt ved tilføjelse af punkt til liste viser sig at ligge inden for en bestemt minimums afstand fra et eksisterende punkt skal disse samles. Dette sker i \texttt{Map}'s \texttt{addVertex metode}, men samme kode. Dette er illustreret i følgende pseudo kode (Liste \ref{lst:snapVertex1}):

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for samling af to punkter, label=lst:snapVertex1]
punkt = find nærmeste-punkt

hvis punkt == tom
    punkt = lav nyt punkt
tilføj punkt til punkt-liste
    
returner punkt
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\subsubsection{MoveMode}
Flytningstilstand (MoveMode), bruges til at flytte rundt på bane-elementer.

I flytnings-tilstand reagere editoren på følgende måde:
\begin{itemize}
    \item Hvis brugeren klikker på et bane-element (punkt, kant polygon) bliver dette markeret som valgt
    \item Hvis brugeren vælger et bane-element og holder museknappen nede, flyttes elementet sammen med musen.
    \item Hvis to punkter (ved flytning af punkter) kommer inden for en minimumsafstand, samles disse til et punkt. 
    \item Hvis brugeren trykker på \texttt{delete}-knappen på sit keyboard, slettes det valgte bane-element.
\end{itemize}

For at vælge et objekt i et Map kaldes \texttt{select} med et punkt som argument. Denne metode undersøger først om der er nogen punkter inden for en bestemt radius. Hvis ikke undersøges for kanter og hvis ingen kanter findes; da undersøges for polygoner. Hver af metoderne ``find nærmeste ...''\ finder nærmeste punkt, kant eller polygon inden for en begrænset radius omkring et punkt. Findes ingenting returneres selve Map. Det kan ses i pseudokode herunder (Liste \ref{lst:select}):

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for valg af bane-element, label=lst:select]
BaneElement element

element = find nærmeste punkt
hvis element ikke tom
    returner element

element = find nærmeste kant
hvis element ikke tom  
    returner element

element = find nærmeste polygon
hvis element ikke tom 
    returner element

returner Bane
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

Hver af disse metoder ``find nærmeste punkt''\, ``find nærmeste kant''\ og ``find nærmeste polygon''\ findes i Map. Logikken i ``find nærmeste punkt''\ med argumentet ``punkt''\ går ca således:

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode til at finde nærmeste punkt, label=lst:nearestpoint]
for alle punkter p i punkt-liste 
    hvis p indeholder punkt
        returner p
    ellers 
        returner tom
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

Metoden undersøger hvorvidt et punkt er indenfor en given radius. Resten af metoderne minder om ovenstående.

Hvis to punkter er tilstrækkelig tæt på hinanden skal de samles som i PolygonMode. Dettes gøres fra MoveMode's input håndtering. I pseudo kode ser det ud som følger:

\begin{center}
\begin{minipage}[t]{0.8\textwidth}
\begin{flushleft}
\begin{lstlisting}[caption=Pseudo-kode for samling af to punkter, label=lst:snapVertex]
nærmestePunkt = find nærmeste-punkt

hvis nærmeste-punkt inden for margin
    for hvert polygon p i Map 
        for hver punkt pk i p 
            hvis pk = p
                pk = nærmeste-punkt
ellers 
    fortsæt
\end{lstlisting}
\end{flushleft}
\end{minipage}
\end{center}

\section{Resultat}

Editoren ser ud til at leve op til alle krav. Et billede af editoren kan ses på figur \ref{fig:ss}


\begin{figure}[h]
\begin{center}
    \begin{minipage}[t]{\textwidth}
        \begin{center}
            \scalebox{0.6}{\includegraphics{gfx/tests/full.jpg}}
            \caption{Editor i fuld funktion, i baggrunden ses en bane med farvede polygoner, i forgrunden en tom bane }
            \label{fig:ss}
        \end{center}
    \end{minipage}
\end{center}
\end{figure}

