package com.game;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;

public class GameRun extends SurfaceView implements Callback {
    private GameThread m_GameThread;
    private CMopMgr     m_cMopMgr   = new CMopMgr();
    private CTowerMgr   m_cTowerMgr = new CTowerMgr();

    class CMop{
        public int  m_nX;
        public int  m_nY;
        public long m_lBeforTime;      
        public long m_nSleep;          
        public int  m_nSpeed;          
        public int  m_nMoveArea;       
        public int  m_nMopHealth;      
        public boolean m_bUsed;        
        public boolean m_bDie;         
        public int  m_nDirection;      
       
        public int  m_aMovePos[][] =
            {
                { 93,   0,   2},   
                { 93,  19,   3},   
                { 23,  19,   2},   
                { 23, 143,   1},   
                { 94, 143,   4},   
                { 94,  95,   1},   
                {206,  95,   2},   
                {206, 215,   3},   
                { 24, 215,   2},   
                { 24, 286,   1},   
                {282, 286,   4},   
                {282,  19,   3},   
                {175,  19,   4},   
                {175,   0,   0}    
            };

        CMop(){
            m_nX            = 93;
            m_nY            = 0;
            m_lBeforTime    = System.currentTimeMillis();  
            m_nSleep        = 10;  
            m_nSpeed        = 2;   
            m_nMoveArea     = 1;   
            m_bUsed         = false;
            m_nMopHealth    = 100; 
            m_bDie          = false;
            m_nDirection    = -1;
        }
       
        public void MovePosition(){
           
            if( (System.currentTimeMillis() - m_lBeforTime) > m_nSleep ){
                m_lBeforTime = System.currentTimeMillis();
            }
            else{
                return;
            }

          
            int nDir = m_aMovePos[m_nMoveArea-1][2];
            if(m_nDirection != nDir){
                m_nDirection = nDir;
            }

           
            if(m_nMoveArea > 13){
                m_nDirection = -1;
                m_nX = 93;
                m_nY =  0;
                m_cMopMgr.m_nOverCount += 1;   
                m_nMoveArea = 1;
                return;
            }

           
            if(nDir == 1){
                m_nX += m_nSpeed;
                if(m_aMovePos[m_nMoveArea][0] < m_nX) m_nMoveArea++;
            }
            else if(nDir == 2){
                m_nY += m_nSpeed;
                if(m_aMovePos[m_nMoveArea][1] < m_nY) m_nMoveArea++;
            }
            else if(nDir == 3){
                m_nX -= m_nSpeed;
                if(m_aMovePos[m_nMoveArea][0] > m_nX) m_nMoveArea++;
            }
            else if(nDir == 4){
                m_nY -= m_nSpeed;
                if(m_aMovePos[m_nMoveArea][1] > m_nY) m_nMoveArea++;
            }
        }
    }

    class CMopMgr{
        public static final int m_nMopCnt   = 20;                  
        public CMop     mop[]               = new CMop[m_nMopCnt]; 
        public int      m_nUsedMopCnt       = 0;                   
        public int      m_nDieMopCnt        = 0;                   
        public long     m_lRegen            = 1000;                
        public int      m_nOverCount        = 0;                   
        public long     m_lBeforRegen       = System.currentTimeMillis();
        CMopMgr(){
            for(int n = 0 ; n < m_nMopCnt ; n++){
                mop[n] = new CMop();
            }
        }

       
        public void AddMop(){
           
            if( (System.currentTimeMillis() - m_lBeforRegen) > m_lRegen){
                m_lBeforRegen = System.currentTimeMillis();
            }
            else return;

            if(m_nUsedMopCnt >= (m_nMopCnt-1))      return;
            mop[m_nUsedMopCnt].m_bUsed = true;

            m_nUsedMopCnt ++;
        }

      
        public void MoveMop(){
            for(int n = 0 ; n < m_nMopCnt ; n++){
                if(mop[n].m_bUsed == true){
                    mop[n].MovePosition();
                }
            }
        }
       
        public int FindMop(int nTowerIndex){
            for(int n = 0 ; n < m_nMopCnt ; n++){

               
                if(mop[n].m_bUsed == false){
                    continue;
                }

                if(mop[n].m_bDie == true){
                    continue;
                }

                int nX = m_cTowerMgr.tower[nTowerIndex].m_nX - mop[n].m_nX;
                int nY = m_cTowerMgr.tower[nTowerIndex].m_nY - mop[n].m_nY;

                int nDistance = nX * nX + nY * nY;
                if(nDistance < 3000) return n;
            }
            return -1;
        }
    }


    class CTower{
        public int      m_nX            = 0;       
        public int      m_nY            = 0;       

        public int      m_nMopIndex;               
        public long     m_lAttackTime   = 0;       
        public long     m_lAttackSleep  = 1500;    
        public boolean  m_bUsed         = false;   

        public boolean  m_bUsedMissale  = false;   
        public int      m_nMissalePos   = 0;       
        public long     m_lMissaleSleep = 8;       
        public long     m_lMissaleTime  = 0;       

        public int      m_nMissaleX     = 0;       
        public int      m_nMissaleY     = 0;       

        void AttackMop(int nMopIndex){
           
            if(m_bUsed == false) return;

           
            if( (System.currentTimeMillis() - m_lAttackTime) > m_lAttackSleep){
                m_lAttackTime = System.currentTimeMillis();
            }
            else return;

           
            if(m_bUsedMissale == true) return;

           
            m_bUsedMissale = true;

           
            m_nMopIndex = nMopIndex;
        }

        void MoveMissale(){
           
            if(m_bUsed == false) return;

           
            if(m_bUsedMissale == false) return;

           
            if( (System.currentTimeMillis() - m_lMissaleTime) > m_lMissaleSleep ){
                m_lMissaleTime = System.currentTimeMillis();
            }
            else return;

           
            if(m_nMissalePos > 6){

               
                m_nMissalePos   = 0;
                m_bUsedMissale  = false;

               
                if(m_cMopMgr.mop[m_nMopIndex].m_nMopHealth < 0){
                    return;
                }
                m_cMopMgr.mop[m_nMopIndex].m_nMopHealth -= 30;
                if(m_cMopMgr.mop[m_nMopIndex].m_nMopHealth <= 0){
                  
                    m_cMopMgr.mop[m_nMopIndex].m_bUsed = false;
                    m_cMopMgr.m_nDieMopCnt  += 1;
                }
                return;
            }

            int nMopX   = m_cMopMgr.mop[m_nMopIndex].m_nX;
            int nMopY   = m_cMopMgr.mop[m_nMopIndex].m_nY;

           
            int nWidth  = m_nX - nMopX;
            int nHeight = m_nY - nMopY;

           
            m_nMissaleX = m_nX - (nWidth  / (8 - m_nMissalePos) );
            m_nMissaleY = m_nY - (nHeight / (8 - m_nMissalePos) );

            m_nMissalePos++;
        }
    }


    class CTowerMgr{
        public static final int m_nTowerCnt = 10;                      
        public CTower   tower[]             = new CTower[m_nTowerCnt]; 
        public int      m_nUsedTowerCnt     = 0;                       
        CTowerMgr(){
            for(int n = 0 ; n < m_nTowerCnt ; n++){
                tower[n] = new CTower();
            }
        }

       
        public void AddTower(int x, int y){
            if(m_nUsedTowerCnt >= m_nTowerCnt)  return;
            tower[m_nUsedTowerCnt].m_bUsed = true;
            tower[m_nUsedTowerCnt].m_nX = x;
            tower[m_nUsedTowerCnt].m_nY = y;
            m_nUsedTowerCnt ++;
        }

        public int GetTowerCount(){
            return m_nUsedTowerCnt;
        }
    }

    class GameThread extends Thread {
        private int             m_nDisplayWidth;   
        private int             m_nDisplayHeight;  
        private Bitmap          m_bmpBg;           
        private Bitmap          m_bmpMop;          
        private Bitmap          m_bmpMissile;      
        private Bitmap          m_bmpTower;        
        private SurfaceHolder   m_SurfaceHolder;
        public  boolean         m_bStop;

        public GameThread (SurfaceHolder surfaceholder, Context context){
            m_SurfaceHolder     = surfaceholder;
            Resources res       = context.getResources();

           
            m_bmpBg             = BitmapFactory.decodeResource(res,R.drawable.bg);
            m_bmpMop            = BitmapFactory.decodeResource(res,R.drawable.mop);
            m_bmpMissile        = BitmapFactory.decodeResource(res,R.drawable.missile);
            m_bmpTower          = BitmapFactory.decodeResource(res,R.drawable.tower);

         
            Display display     =
                ((WindowManager)context.getSystemService(context.WINDOW_SERVICE)).getDefaultDisplay();

            m_nDisplayWidth     = display.getWidth();
            m_nDisplayHeight    = display.getHeight();

           
            m_bStop             = false;
        }

        public void run(){
            while(!m_bStop){
                Canvas canvas = null;
                try {
                    canvas = m_SurfaceHolder.lockCanvas(null);
                    synchronized(m_SurfaceHolder){
                        Rect rcSrc  = new Rect();
                        Rect rcDest = new Rect();

                        rcSrc.set(0,0,470,498);
                        rcDest.set(0,0,m_nDisplayHeight,m_nDisplayHeight);

                       
                        canvas.drawBitmap(m_bmpBg       , rcSrc, rcDest, null);

                      
                        m_cMopMgr.AddMop();
                        m_cMopMgr.MoveMop();

                       
                        for(int n = 0 ; n < m_cMopMgr.m_nMopCnt ; n++){
                            if(m_cMopMgr.mop[n].m_bUsed == true){
                                canvas.drawBitmap(m_bmpMop      ,m_cMopMgr.mop[n].m_nX,m_cMopMgr.mop[n].m_nY, null);
                            }
                        }

                        for(int n = 0 ; n <m_cTowerMgr.m_nTowerCnt ; n++){
                            if(m_cTowerMgr.tower[n].m_bUsed == true){
                                canvas.drawBitmap(m_bmpTower      ,m_cTowerMgr.tower[n].m_nX,m_cTowerMgr.tower[n].m_nY, null);

                               
                                if(m_cTowerMgr.tower[n].m_bUsedMissale){
                                    canvas.drawBitmap(m_bmpMissile ,m_cTowerMgr.tower[n].m_nMissaleX,m_cTowerMgr.tower[n].m_nMissaleY, null);
                                }
                                else{  
                                    int nMop = m_cMopMgr.FindMop(n);
                                    if(nMop >= 0){
                                        m_cTowerMgr.tower[n].AttackMop(nMop);
                                    }
                                }
                                m_cTowerMgr.tower[n].MoveMissale();
                            }
                        }
                        Paint paint = new Paint();
                        paint.setStyle(Paint.Style.FILL);
                        paint.setColor(Color.WHITE); 
                        canvas.drawText( " 타워 설치 가능 : "  + (m_cTowerMgr.m_nTowerCnt - m_cTowerMgr.GetTowerCount() ) ,5,20, paint);
                        canvas.drawText( " 아웃 카운트 : " + (10 - m_cMopMgr.m_nOverCount),5,40, paint);

                        sleep(10);
                    }
                }
                catch (InterruptedException e){
                    e.printStackTrace();
                }
                finally{
                    if(canvas != null){
                        m_SurfaceHolder.unlockCanvasAndPost(canvas);
                    }
                }
            }
        }
        void AddTower(int x, int y){
            m_cTowerMgr.AddTower(x-8,y-12);
        }
    }
    public GameRun(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        SurfaceHolder holder = getHolder();
        holder.addCallback(this);

        m_GameThread = new GameThread(holder, context);
    }
   
    public boolean gameOver;

 

   
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        if(event.getAction() == MotionEvent.ACTION_UP){
            m_GameThread.AddTower((int)event.getX(), (int)event.getY());
        }
        return true;
    }

    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
        // TODO Auto-generated method stub

    }

    public void surfaceCreated(SurfaceHolder arg0) {
        // TODO Auto-generated method stub

        m_GameThread.start();
    }

    public void surfaceDestroyed(SurfaceHolder arg0) {
        // TODO Auto-generated method stub

    }
}

지금 하고 있는 소스인대 제가 한건 아니고 한조에 잘하는 애가 한것인대 그 잘하는애가 갑자기 병원을 가게되서 다음주까지 완성시켜야 하는대요 현재 게임이 아웃카운트가 100이 되면 게임오버->메인메뉴로 돌아가기 몬스터를 전부 죽였다 미션 승리 다시 메인화면을 돌아가는걸로 마무리를 지을껀대요 게임오버와 게임클리어 장면을 어떤 소소코드를 집어넣어야 할까요? 현재는 카운트 수가 100이되든 천이되던 끝나질 않더군요 몬스터를 다 잡으면 클리어 되는 장면나오고 메인화면으로 돌아가는걸로 할려고 합니다